Skip to content

Commit

Permalink
fix(react-scheduler): display time in Time Scale correctly when a DST…
Browse files Browse the repository at this point in the history
… change is present (#3198)
  • Loading branch information
AryamnovEugeniy committed Dec 10, 2020
1 parent 087eb69 commit d1247fb
Show file tree
Hide file tree
Showing 12 changed files with 392 additions and 32 deletions.
26 changes: 23 additions & 3 deletions packages/dx-react-scheduler/src/plugins/day-view.test.tsx
Expand Up @@ -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';
Expand All @@ -18,6 +21,7 @@ jest.mock('@devexpress/dx-scheduler-core', () => ({
availableViews: jest.fn(),
calculateWeekDateIntervals: jest.fn(),
getTimeTableHeight: jest.fn(),
timeCellsData: jest.fn(),
}));

const defaultDeps = {
Expand Down Expand Up @@ -58,6 +62,7 @@ describe('Day View', () => {
(getters, viewName, baseComputed) => baseComputed(getters, viewName),
);
global.Date.now = () => 123;
timeCellsData.mockImplementation(() => 'timeCellsData');
});
afterEach(() => {
jest.resetAllMocks();
Expand Down Expand Up @@ -108,6 +113,21 @@ describe('Day View', () => {
expect(calculateWeekDateIntervals)
.toHaveBeenCalledWith(2, 3, 4, 5, 1);
});

it('should export timeCellsData getter', () => {
const tree = mount((
<PluginHost>
{pluginDepsToComponents(defaultDeps)}
<DayView {...defaultProps} />
</PluginHost>
));

expect(timeCellsData)
.toBeCalledWith(undefined, 0, 24, 30, expect.any(Number));

expect(getComputedState(tree).timeCellsData)
.toBe('timeCellsData');
});
});

describe('Templates', () => {
Expand All @@ -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,
});
});
Expand Down
31 changes: 27 additions & 4 deletions packages/dx-react-scheduler/src/plugins/day-view.tsx
Expand Up @@ -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';

Expand All @@ -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 = () => <TemplatePlaceholder name="timeScale" />;

class DayViewBase extends React.PureComponent<VerticalViewProps> {
Expand Down Expand Up @@ -57,6 +67,13 @@ class DayViewBase extends React.PureComponent<VerticalViewProps> {
timeTableRowComponent: 'TimeTableRow',
};

timeCellsDataComputed = memoize((viewName, startDayHour, endDayHour) => getters => computed(
getters,
viewName,
timeCellsDataComputed(startDayHour, endDayHour),
getters.timeCellsData,
));

render() {
const {
layoutComponent,
Expand Down Expand Up @@ -108,22 +125,28 @@ class DayViewBase extends React.PureComponent<VerticalViewProps> {
}}
/>

<Getter
name="timeCellsData"
computed={this.timeCellsDataComputed(viewName, startDayHour, endDayHour)}
/>

<Template name="timeScale">
{(params: any) => (
<TemplateConnector>
{({
currentView, viewCellsData, groups, formatDate,
currentView, timeCellsData, groups, formatDate,
groupOrientation: getGroupOrientation,
timeTableElementsMeta,
}) => {
if (currentView.name !== viewName) return <TemplatePlaceholder />;
const groupOrientation = getGroupOrientation?.(viewName);

return (
<TimeScale
labelComponent={TimeScaleLabel}
tickCellComponent={timeScaleTickCellComponent}
rowComponent={timeScaleTicksRowComponent}
cellsData={viewCellsData}
cellsData={timeCellsData}
formatDate={formatDate}
groups={groups}
groupOrientation={groupOrientation}
Expand Down
Expand Up @@ -3,9 +3,15 @@ import { mount } from 'enzyme';
import { PluginHost } from '@devexpress/dx-react-core';
import { pluginDepsToComponents, getComputedState } from '@devexpress/dx-testing';
import {
getGroupsFromResources, expandViewCellsDataWithGroups,
sortFilteredResources, filterResourcesByGrouping, updateGroupingWithMainResource,
expandGroups, updateAllDayCellElementsMeta, updateTimeTableCellElementsMeta,
getGroupsFromResources,
expandViewCellsDataWithGroups,
sortFilteredResources,
filterResourcesByGrouping,
updateGroupingWithMainResource,
expandGroups,
updateAllDayCellElementsMeta,
updateTimeTableCellElementsMeta,
updateTimeCellsData,
} from '@devexpress/dx-scheduler-core';
import { IntegratedGrouping } from './integrated-grouping';

Expand All @@ -19,6 +25,7 @@ jest.mock('@devexpress/dx-scheduler-core', () => ({
expandGroups: jest.fn(),
updateTimeTableCellElementsMeta: jest.fn(),
updateAllDayCellElementsMeta: jest.fn(),
updateTimeCellsData: jest.fn(),
}));

describe('IntegratedGrouping', () => {
Expand All @@ -38,6 +45,7 @@ describe('IntegratedGrouping', () => {
allDayElementsMeta: 'allDayElementsMeta',
timeTableElementsMeta: 'timeTableElementsMeta',
allDayPanelExists: 'allDayPanelExists',
timeCellsData: 'timeCellsData',
},
};
beforeEach(() => {
Expand All @@ -49,6 +57,7 @@ describe('IntegratedGrouping', () => {
expandGroups.mockImplementation(() => 'expandGroups');
updateTimeTableCellElementsMeta.mockImplementation(() => 'timeTableElementsMeta updated');
updateAllDayCellElementsMeta.mockImplementation(() => 'allDayElementsMeta updated');
updateTimeCellsData.mockImplementation(() => 'timeCellsData updated');
});
afterEach(jest.resetAllMocks);

Expand Down Expand Up @@ -124,6 +133,38 @@ describe('IntegratedGrouping', () => {
.toBe('groupedViewCellsData');
});

it('should provide timeCellsData getter', () => {
const tree = mount((
<PluginHost>
{pluginDepsToComponents(defaultDeps)}
<IntegratedGrouping />
</PluginHost>
));

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((
<PluginHost>
{pluginDepsToComponents(defaultDeps, {
getter: {
timeCellsData: undefined,
},
})}
<IntegratedGrouping />
</PluginHost>
));

expect(updateTimeCellsData)
.toHaveBeenCalledTimes(0);
expect(getComputedState(tree).timeCellsData)
.toBe(undefined);
});

it('should provide timeTableAppointments getter', () => {
const tree = mount((
<PluginHost>
Expand Down
15 changes: 14 additions & 1 deletion packages/dx-react-scheduler/src/plugins/integrated-grouping.tsx
Expand Up @@ -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';

Expand Down Expand Up @@ -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<IntegratedGroupingProps> = React.memo(() => (
<Plugin
name="IntegratedGrouping"
Expand All @@ -90,6 +102,7 @@ const IntegratedGroupingBase: React.SFC<IntegratedGroupingProps> = React.memo(()

<Getter name="viewCellsData" computed={getViewCellsDataComputed} />
<Getter name="allDayCellsData" computed={getAllDayCellsDataComputed} />
<Getter name="timeCellsData" computed={getTimeCellsDataComputed} />

<Getter name="timeTableAppointments" computed={getTimeTableAppointmentsComputed} />
<Getter name="allDayAppointments" computed={getAllDayAppointmentsComputed} />
Expand Down
26 changes: 23 additions & 3 deletions packages/dx-react-scheduler/src/plugins/week-view.test.tsx
Expand Up @@ -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';
Expand All @@ -19,6 +22,7 @@ jest.mock('@devexpress/dx-scheduler-core', () => ({
availableViews: jest.fn(),
calculateWeekDateIntervals: jest.fn(),
getTimeTableHeight: jest.fn(),
timeCellsData: jest.fn(),
}));

const defaultDeps = {
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -110,6 +115,21 @@ describe('Week View', () => {
expect(calculateWeekDateIntervals)
.toHaveBeenCalledWith(2, 3, 4, 5, 1);
});

it('should export timeCellsData getter', () => {
const tree = mount((
<PluginHost>
{pluginDepsToComponents(defaultDeps)}
<WeekView {...defaultProps} />
</PluginHost>
));

expect(timeCellsData)
.toBeCalledWith(undefined, 0, 24, 30, expect.any(Number));

expect(getComputedState(tree).timeCellsData)
.toBe('timeCellsData');
});
});

describe('Templates', () => {
Expand All @@ -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,
});
});
Expand Down
31 changes: 27 additions & 4 deletions packages/dx-react-scheduler/src/plugins/week-view.tsx
Expand Up @@ -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 = (
Expand All @@ -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 = () => <TemplatePlaceholder name="timeScale" />;

class WeekViewBase extends React.PureComponent<WeekViewProps> {
Expand Down Expand Up @@ -59,6 +69,13 @@ class WeekViewBase extends React.PureComponent<WeekViewProps> {
timeTableRowComponent: 'TimeTableRow',
};

timeCellsDataComputed = memoize((viewName, startDayHour, endDayHour) => getters => computed(
getters,
viewName,
timeCellsDataComputed(startDayHour, endDayHour),
getters.timeCellsData,
));

render() {
const {
layoutComponent,
Expand Down Expand Up @@ -112,22 +129,28 @@ class WeekViewBase extends React.PureComponent<WeekViewProps> {
}}
/>

<Getter
name="timeCellsData"
computed={this.timeCellsDataComputed(viewName, startDayHour, endDayHour)}
/>

<Template name="timeScale">
{(params: any) => (
<TemplateConnector>
{({
currentView, viewCellsData, groups, formatDate,
currentView, timeCellsData, groups, formatDate,
groupOrientation: getGroupOrientation,
timeTableElementsMeta,
}) => {
if (currentView.name !== viewName) return <TemplatePlaceholder />;
const groupOrientation = getGroupOrientation?.(viewName);

return (
<TimeScale
labelComponent={TimeScaleLabel}
tickCellComponent={timeScaleTickCellComponent}
rowComponent={timeScaleTicksRowComponent}
cellsData={viewCellsData}
cellsData={timeCellsData}
formatDate={formatDate}
groups={groups}
groupOrientation={groupOrientation}
Expand Down

0 comments on commit d1247fb

Please sign in to comment.