Skip to content

Commit c851a48

Browse files
refactor(react-scheduler): transfer DOM operations into theme package (#2068)
BREAKING CHANGE: `AllDayPanel` plugin's layout component now doesn't have the `allDayPanel` property. To specify cell elements use `setCellElementsMeta` property. ```diff ... <AllDayyPanel layoutComponent={({ - allDayPanelRef, + setCellElementsMeta, ...restProps }) => ( <AllDayPanel.Layout> - allDayPanelRef={allDayPanelRef} + setCellElementsMeta={setCellElementsMeta} {...restProps} /> )} /> ... ```
1 parent ffc4681 commit c851a48

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+1041
-904
lines changed

packages/dx-react-scheduler-material-ui/src/plugins/day-view.jsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import { Container as AppointmentLayer } from '../templates/appointment/containe
99
import { Layout as TimeScaleLayout } from '../templates/views/vertical/time-scale/layout';
1010
import { Cell as TimeScaleCell } from '../templates/views/vertical/time-scale/cell';
1111

12-
import { TimeTableContainer } from '../templates/views/common/time-table/layout-container';
1312
import { Layout as TimeTableLayout } from '../templates/views/vertical/time-table/layout';
1413
import { Cell as TimeTableCell } from '../templates/views/vertical/time-table/cell';
1514

@@ -27,7 +26,6 @@ export const DayView = withComponents({
2726
DayScaleLayout,
2827
DayScaleCell,
2928
DayScaleRow: Row,
30-
TimeTableContainer,
3129
TimeTableLayout,
3230
TimeTableCell,
3331
TimeTableRow: Row,

packages/dx-react-scheduler-material-ui/src/plugins/month-view.jsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { HorizontalViewLayout as Layout } from '../templates/layouts/horizontal-
55
import { Row } from '../templates/views/common/row';
66
import { Container as AppointmentLayer } from '../templates/appointment/container';
77

8-
import { TimeTableContainer } from '../templates/views/common/time-table/layout-container';
98
import { Layout as TimeTableLayout } from '../templates/views/horizontal/time-table/layout';
109
import { Cell as TimeTableCell } from '../templates/views/horizontal/time-table/cell';
1110

@@ -18,7 +17,6 @@ export const MonthView = withComponents({
1817
DayScaleLayout,
1918
DayScaleCell,
2019
DayScaleRow: Row,
21-
TimeTableContainer,
2220
TimeTableLayout,
2321
TimeTableCell,
2422
TimeTableRow: Row,

packages/dx-react-scheduler-material-ui/src/plugins/week-view.jsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import { Container as AppointmentLayer } from '../templates/appointment/containe
99
import { Layout as TimeScaleLayout } from '../templates/views/vertical/time-scale/layout';
1010
import { Cell as TimeScaleCell } from '../templates/views/vertical/time-scale/cell';
1111

12-
import { TimeTableContainer } from '../templates/views/common/time-table/layout-container';
1312
import { Layout as TimeTableLayout } from '../templates/views/vertical/time-table/layout';
1413
import { Cell as TimeTableCell } from '../templates/views/vertical/time-table/cell';
1514

@@ -26,7 +25,6 @@ export const WeekView = withComponents({
2625
DayScaleLayout,
2726
DayScaleCell,
2827
DayScaleRow: Row,
29-
TimeTableContainer,
3028
TimeTableLayout,
3129
TimeTableCell,
3230
TimeTableRow: Row,
Lines changed: 63 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,86 @@
11
import * as React from 'react';
22
import * as PropTypes from 'prop-types';
33
import Table from '@material-ui/core/Table';
4-
import TableHead from '@material-ui/core/TableHead';
4+
import TableBody from '@material-ui/core/TableBody';
55
import { withStyles } from '@material-ui/core/styles';
66
import classNames from 'classnames';
7+
import { cellsMeta } from '../utils';
78

89
const styles = {
910
table: {
1011
tableLayout: 'fixed',
1112
},
1213
};
1314

14-
const LayoutBase = ({
15-
cellsData,
16-
allDayPanelRef,
17-
classes, className,
18-
cellComponent: Cell,
19-
rowComponent: Row,
20-
...restProps
21-
}) => (
22-
<Table
23-
className={classNames(classes.table, className)}
24-
ref={allDayPanelRef}
25-
{...restProps}
26-
>
27-
<TableHead>
28-
<Row>
29-
{cellsData.map(({
30-
startDate,
31-
endDate,
32-
}) => (
33-
<Cell
34-
key={startDate}
35-
startDate={startDate}
36-
endDate={endDate}
37-
/>
38-
))}
39-
</Row>
40-
</TableHead>
41-
</Table>
42-
);
15+
class LayoutBase extends React.PureComponent {
16+
constructor(props) {
17+
super(props);
18+
19+
this.table = React.createRef();
20+
}
21+
22+
componentDidMount() {
23+
this.setCells();
24+
}
25+
26+
componentDidUpdate() {
27+
this.setCells();
28+
}
29+
30+
setCells() {
31+
const { setCellElementsMeta } = this.props;
32+
33+
const tableElement = this.table.current;
34+
setCellElementsMeta(cellsMeta(tableElement));
35+
}
36+
37+
render() {
38+
const {
39+
setCellElementsMeta,
40+
cellsData,
41+
classes, className,
42+
cellComponent: Cell,
43+
rowComponent: Row,
44+
formatDate,
45+
...restProps
46+
} = this.props;
47+
48+
return (
49+
<Table
50+
ref={this.table}
51+
className={classNames(classes.table, className)}
52+
{...restProps}
53+
>
54+
<TableBody>
55+
<Row>
56+
{cellsData.map(({
57+
startDate,
58+
endDate,
59+
}) => (
60+
<Cell
61+
key={startDate}
62+
startDate={startDate}
63+
endDate={endDate}
64+
/>
65+
))}
66+
</Row>
67+
</TableBody>
68+
</Table>
69+
);
70+
}
71+
}
4372

4473
LayoutBase.propTypes = {
45-
allDayPanelRef: PropTypes.func.isRequired,
4674
classes: PropTypes.object.isRequired,
75+
formatDate: PropTypes.func.isRequired,
4776
cellsData: PropTypes.arrayOf(Array).isRequired,
48-
cellComponent: PropTypes.func,
49-
rowComponent: PropTypes.func,
77+
cellComponent: PropTypes.func.isRequired,
78+
rowComponent: PropTypes.func.isRequired,
79+
setCellElementsMeta: PropTypes.func.isRequired,
5080
className: PropTypes.string,
5181
};
5282
LayoutBase.defaultProps = {
5383
className: undefined,
54-
cellComponent: () => null,
55-
rowComponent: () => null,
5684
};
5785

5886
export const Layout = withStyles(styles, { name: 'Layout' })(LayoutBase);
Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,34 @@
11
import * as React from 'react';
2-
import { createShallow, getClasses } from '@material-ui/core/test-utils';
2+
import { getClasses, createMount } from '@material-ui/core/test-utils';
33
import { Layout } from './layout';
44

55
describe('AllDayPanel', () => {
66
let classes;
7-
let shallow;
7+
let mount;
88
const defaultProps = {
9-
allDayPanelRef: () => null,
9+
setCellElementsMeta: jest.fn(),
1010
cellsData: [{ startDate: 1 }, { startDate: 2 }],
11+
cellComponent: () => <td />,
12+
/* eslint-disable-next-line */
13+
rowComponent: ({ children }) => <tr>{children}</tr>,
1114
};
1215
beforeAll(() => {
1316
classes = getClasses(
1417
<Layout {...defaultProps}>
1518
<div />
1619
</Layout>,
1720
);
18-
shallow = createShallow({ dive: true });
21+
});
22+
beforeEach(() => {
23+
mount = createMount();
24+
});
25+
afterEach(() => {
26+
jest.resetAllMocks();
27+
mount.cleanUp();
1928
});
2029
describe('Layout', () => {
2130
it('should pass className to the root element', () => {
22-
const tree = shallow((
31+
const tree = mount((
2332
<Layout {...defaultProps} className="custom-class">
2433
<div />
2534
</Layout>
@@ -31,18 +40,18 @@ describe('AllDayPanel', () => {
3140
.toBeTruthy();
3241
});
3342
it('should pass rest props to the root element', () => {
34-
const tree = shallow((
43+
const tree = mount((
3544
<Layout {...defaultProps} data={{ a: 1 }}>
3645
<div />
3746
</Layout>
3847
));
3948

40-
expect(tree.find(`.${classes.table}`).props().data)
49+
expect(tree.find(`.${classes.table}`).at(0).props().data)
4150
.toMatchObject({ a: 1 });
4251
});
4352
it('should render array of days', () => {
4453
const cell = () => <td />;
45-
const tree = shallow((
54+
const tree = mount((
4655
<Layout {...defaultProps} cellComponent={cell}>
4756
<div />
4857
</Layout>
@@ -51,5 +60,20 @@ describe('AllDayPanel', () => {
5160
expect(tree.find(cell))
5261
.toHaveLength(2);
5362
});
63+
it('should calls setCellElementsMeta', () => {
64+
const tree = mount((
65+
<Layout
66+
{...defaultProps}
67+
/>
68+
));
69+
70+
expect(defaultProps.setCellElementsMeta)
71+
.toBeCalledTimes(1);
72+
73+
tree.setProps({ className: 'a' });
74+
75+
expect(defaultProps.setCellElementsMeta)
76+
.toBeCalledTimes(2);
77+
});
5478
});
5579
});

packages/dx-react-scheduler-material-ui/src/templates/layouts/horizontal-view-layout.jsx

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { AUTO_HEIGHT } from '@devexpress/dx-scheduler-core';
44
import Grid from '@material-ui/core/Grid';
55
import { withStyles } from '@material-ui/core/styles';
66
import classNames from 'classnames';
7+
import { scrollingStrategy } from '../utils';
78

89
const styles = theme => ({
910
container: {
@@ -17,29 +18,50 @@ const styles = theme => ({
1718
overflow: 'visible',
1819
background: theme.palette.background.paper,
1920
},
20-
main: {
21+
timeTable: {
2122
position: 'relative',
2223
},
2324
});
2425

25-
export class HorizontalViewLayoutBase extends React.PureComponent {
26+
class HorizontalViewLayoutBase extends React.PureComponent {
27+
constructor(props) {
28+
super(props);
29+
30+
this.layout = React.createRef();
31+
this.layoutHeader = React.createRef();
32+
}
33+
34+
componentDidMount() {
35+
this.setScrollingStrategy();
36+
}
37+
38+
componentDidUpdate() {
39+
this.setScrollingStrategy();
40+
}
41+
42+
setScrollingStrategy() {
43+
const { setScrollingStrategy } = this.props;
44+
45+
setScrollingStrategy(scrollingStrategy(this.layout.current, this.layoutHeader.current));
46+
}
47+
2648
render() {
2749
const {
28-
dayScaleComponent: Navbar,
29-
timeTableComponent: Main,
50+
dayScaleComponent: DayScale,
51+
timeTableComponent: TimeTable,
52+
setScrollingStrategy,
3053
classes,
31-
layoutRef,
32-
layoutHeaderRef,
3354
height,
3455
className,
3556
style,
3657
...restProps
3758
} = this.props;
3859

3960
const containerStyle = height === AUTO_HEIGHT ? { height: '100%' } : { height: `${height}px` };
61+
4062
return (
4163
<Grid
42-
ref={layoutRef}
64+
ref={this.layout}
4365
className={classNames(classes.container, className)}
4466
container
4567
direction="column"
@@ -48,17 +70,17 @@ export class HorizontalViewLayoutBase extends React.PureComponent {
4870
{...restProps}
4971
>
5072
<Grid
51-
ref={layoutHeaderRef}
73+
ref={this.layoutHeader}
5274
item
5375
className={classes.stickyHeader}
5476
>
55-
<Navbar />
77+
<DayScale />
5678
</Grid>
5779
<Grid
5880
item
59-
className={classes.main}
81+
className={classes.timeTable}
6082
>
61-
<Main />
83+
<TimeTable />
6284
</Grid>
6385
</Grid>
6486
);
@@ -69,10 +91,9 @@ HorizontalViewLayoutBase.propTypes = {
6991
// oneOfType is a workaround because withStyles returns react object
7092
dayScaleComponent: PropTypes.oneOfType([PropTypes.func, PropTypes.object]).isRequired,
7193
timeTableComponent: PropTypes.oneOfType([PropTypes.func, PropTypes.object]).isRequired,
72-
classes: PropTypes.object.isRequired,
73-
layoutRef: PropTypes.object.isRequired,
74-
layoutHeaderRef: PropTypes.object.isRequired,
94+
setScrollingStrategy: PropTypes.func.isRequired,
7595
height: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
96+
classes: PropTypes.object.isRequired,
7697
className: PropTypes.string,
7798
style: PropTypes.object,
7899
};

packages/dx-react-scheduler-material-ui/src/templates/layouts/horizontal-view-layout.test.jsx

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,25 @@
11
import * as React from 'react';
22
import { getClasses, createShallow } from '@material-ui/core/test-utils';
33
import { HorizontalViewLayout } from './horizontal-view-layout';
4+
import { scrollingStrategy } from '../utils';
5+
6+
jest.mock('../utils', () => ({
7+
scrollingStrategy: jest.fn(),
8+
}));
49

510
describe('Horizontal View Layout', () => {
611
const defaultProps = {
712
dayScaleComponent: () => null,
813
timeTableComponent: () => null,
9-
layoutRef: React.createRef(),
10-
layoutHeaderRef: React.createRef(),
1114
height: 1000,
15+
setScrollingStrategy: jest.fn(),
1216
};
1317
let classes;
1418
let shallow;
1519
beforeAll(() => {
1620
classes = getClasses(<HorizontalViewLayout {...defaultProps} />);
1721
shallow = createShallow({ dive: true });
22+
scrollingStrategy.mockImplementation(() => undefined);
1823
});
1924

2025
it('should pass className to the root element', () => {
@@ -54,4 +59,14 @@ describe('Horizontal View Layout', () => {
5459
expect(tree.prop('style'))
5560
.toMatchObject({ height: 1 });
5661
});
62+
63+
it('should call the scrollingStrategy function', () => {
64+
scrollingStrategy.mockClear();
65+
shallow((
66+
<HorizontalViewLayout {...defaultProps} />
67+
));
68+
69+
expect(scrollingStrategy)
70+
.toBeCalledTimes(1);
71+
});
5772
});

0 commit comments

Comments
 (0)