Skip to content

Commit 68609b9

Browse files
authored
Scheduler(T1251590): fix dateCellTemplate async double render (DevExpress#29506)
1 parent df67e7c commit 68609b9

25 files changed

+217
-156
lines changed

e2e/testcafe-devextreme/tests/scheduler/common/layout/templates/cellTemplate.ts

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ const SCHEDULER_SELECTOR = '#container';
3939
});
4040
});
4141

42-
test('Async dateCellTemplate should be rendered only once (T1251590)', async (t) => {
42+
test('[T1251590] Async dateCellTemplate should be rendered only once', async (t) => {
4343
const scheduler = new Scheduler(SCHEDULER_SELECTOR);
4444

4545
const firstTableCell = scheduler.headerPanel.headerCells.nth(0);
@@ -54,12 +54,51 @@ test('Async dateCellTemplate should be rendered only once (T1251590)', async (t)
5454
allDay: true,
5555
},
5656
],
57+
dateCellTemplate: ClientFunction((_, __, itemElement) => {
58+
setTimeout(() => {
59+
itemElement.append('TEST');
60+
}, 0);
61+
}),
5762
currentDate: '2024-01-01',
5863
currentView: 'week',
64+
});
65+
});
66+
67+
test('[T1251590] Async dateCellTemplate should be rendered only once if has reference props (grouping)', async (t) => {
68+
const scheduler = new Scheduler(SCHEDULER_SELECTOR);
69+
70+
const firstTableCell = scheduler.headerPanel.headerCells.nth(0);
71+
72+
await t.expect(firstTableCell.textContent).eql('TEST');
73+
}).before(async () => {
74+
await createWidget('dxScheduler', {
75+
dataSource: [
76+
{
77+
startDate: '2024-01-01T01:00:00',
78+
endDate: '2024-01-01T02:00:00',
79+
allDay: true,
80+
},
81+
],
82+
groups: ['groupId'],
83+
resources: [
84+
{
85+
label: 'group',
86+
fieldExpr: 'groupId',
87+
dataSource: [
88+
{
89+
text: 'A',
90+
id: 0,
91+
color: '#00af2c',
92+
},
93+
],
94+
},
95+
],
5996
dateCellTemplate: ClientFunction((_, __, itemElement) => {
6097
setTimeout(() => {
6198
itemElement.append('TEST');
6299
}, 0);
63100
}),
101+
currentDate: '2024-01-01',
102+
currentView: 'week',
64103
});
65104
});

packages/devextreme/js/__internal/scheduler/r1/components/base/all_day_panel_cell.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { BaseInfernoComponent } from '@ts/core/r1/runtime/inferno/index';
2-
import { getTemplate } from '@ts/core/r1/utils/index';
32

43
import { ALL_DAY_PANEL_CELL_CLASS } from '../const';
54
import type { DateTableCellBaseProps } from './date_table_cell_base';
@@ -21,7 +20,6 @@ export class AllDayPanelCell extends BaseInfernoComponent<DateTableCellBaseProps
2120
isSelected,
2221
startDate,
2322
} = this.props;
24-
const DataCellTemplateComponent = getTemplate(dataCellTemplate);
2523

2624
return (
2725
<DateTableCellBase
@@ -35,7 +33,7 @@ export class AllDayPanelCell extends BaseInfernoComponent<DateTableCellBaseProps
3533
isFirstGroupCell={isFirstGroupCell}
3634
isLastGroupCell={isLastGroupCell}
3735
index={index}
38-
dataCellTemplate={DataCellTemplateComponent}
36+
dataCellTemplate={dataCellTemplate}
3937
isSelected={isSelected}
4038
isFocused={isFocused}
4139
/>

packages/devextreme/js/__internal/scheduler/r1/components/base/all_day_panel_table.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import type { InfernoEffect } from '@ts/core/r1/runtime/inferno/index';
22
import { createReRenderEffect, InfernoWrapperComponent } from '@ts/core/r1/runtime/inferno/index';
33
import type { RefObject } from '@ts/core/r1/types';
4-
import { getTemplate } from '@ts/core/r1/utils/index';
54
import type { ViewCellData } from '@ts/scheduler/r1/types';
65

76
import { DefaultSizes } from '../const';
@@ -47,7 +46,6 @@ export class AllDayTable extends InfernoWrapperComponent<AllDayPanelTableProps>
4746
dataCellTemplate,
4847
} = this.props;
4948
const allDayPanelData = this.getAllDayPanelData();
50-
const DataCellTemplateComponent = getTemplate(dataCellTemplate);
5149

5250
return (
5351
<Table
@@ -65,7 +63,7 @@ export class AllDayTable extends InfernoWrapperComponent<AllDayPanelTableProps>
6563
?? AllDayPanelTableBodyDefaultProps.rightVirtualCellWidth}
6664
leftVirtualCellCount={viewData.leftVirtualCellCount}
6765
rightVirtualCellCount={viewData.rightVirtualCellCount}
68-
dataCellTemplate={DataCellTemplateComponent}
66+
dataCellTemplate={dataCellTemplate}
6967
/>
7068
</Table>
7169
);

packages/devextreme/js/__internal/scheduler/r1/components/base/all_day_panel_table_body.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import type { PropsWithClassName } from '__internal/core/r1';
22
import { BaseInfernoComponent } from '@ts/core/r1/runtime/inferno/index';
33
import type { JSXTemplate } from '@ts/core/r1/types';
4-
import { getTemplate } from '@ts/core/r1/utils/index';
54

65
import { combineClasses } from '../../../../core/r1/utils/render_utils';
76
import type { ViewCellData } from '../../types';
@@ -46,7 +45,6 @@ export class AllDayPanelTableBody extends BaseInfernoComponent<AllDayPanelTableB
4645
'dx-scheduler-all-day-table-row': true,
4746
[className ?? '']: !!className,
4847
});
49-
const DataCellTemplateComponent = getTemplate(dataCellTemplate);
5048

5149
return (
5250
<Row
@@ -79,7 +77,7 @@ export class AllDayPanelTableBody extends BaseInfernoComponent<AllDayPanelTableB
7977
groups={groups}
8078
groupIndex={cellGroupIndex}
8179
index={cellIndex}
82-
dataCellTemplate={DataCellTemplateComponent}
80+
dataCellTemplate={dataCellTemplate}
8381
isSelected={isSelected ?? false}
8482
isFocused={isFocused ?? false}
8583
/>

packages/devextreme/js/__internal/scheduler/r1/components/base/date_header.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { BaseInfernoComponent } from '@ts/core/r1/runtime/inferno/index';
22
import type { JSXTemplate } from '@ts/core/r1/types';
3-
import { getTemplate } from '@ts/core/r1/utils/index';
43

54
import type { DateHeaderData, Group, GroupOrientation } from '../../types';
65
import { isHorizontalGroupingApplied, themeUtils } from '../../utils/index';
@@ -46,7 +45,6 @@ export class DateHeader extends BaseInfernoComponent<DateHeaderProps> {
4645
} = this.props;
4746
const isHorizontalGrouping = isHorizontalGroupingApplied(groups, groupOrientation)
4847
&& !groupByDate;
49-
const DateCellTemplateComponent = getTemplate(dateCellTemplate);
5048

5149
return (
5250
<>
@@ -89,7 +87,7 @@ export class DateHeader extends BaseInfernoComponent<DateHeaderProps> {
8987
text={text}
9088
isFirstGroupCell={isFirstGroupCell}
9189
isLastGroupCell={isLastGroupCell}
92-
dateCellTemplate={DateCellTemplateComponent}
90+
dateCellTemplate={dateCellTemplate}
9391
colSpan={colSpan}
9492
splitText={isMaterialBased}
9593
/>

packages/devextreme/js/__internal/scheduler/r1/components/base/date_header_cell.tsx

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { BaseInfernoComponent } from '@ts/core/r1/runtime/inferno/index';
22
import type { JSXTemplate } from '@ts/core/r1/types';
3-
import { getTemplate } from '@ts/core/r1/utils/index';
3+
import { PublicTemplate } from '@ts/scheduler/r1/components/templates/index';
44

55
import { combineClasses } from '../../../../core/r1/utils/render_utils';
66
import { renderUtils } from '../../utils/index';
@@ -62,30 +62,36 @@ export class DateHeaderCell extends BaseInfernoComponent<DateHeaderCellProps> {
6262
.getGroupCellClasses(isFirstGroupCell, isLastGroupCell, cellClasses);
6363
const useTemplate = (!isTimeCellTemplate && !!dateCellTemplate)
6464
|| (isTimeCellTemplate && !!timeCellTemplate);
65-
const TimeCellTemplateComponent = getTemplate(timeCellTemplate);
66-
const DateCellTemplateComponent = getTemplate(dateCellTemplate);
6765

6866
const children = useTemplate ? (
6967
// this is a workaround for https://github.com/DevExpress/devextreme-renovation/issues/574
7068
<>
71-
{isTimeCellTemplate && TimeCellTemplateComponent?.({
72-
data: {
73-
date: startDate,
74-
text,
75-
groups,
76-
groupIndex,
77-
},
78-
index,
79-
})}
80-
{!isTimeCellTemplate && DateCellTemplateComponent?.({
81-
data: {
82-
date: startDate,
83-
text,
84-
groups,
85-
groupIndex,
86-
},
87-
index,
88-
})}
69+
{isTimeCellTemplate
70+
&& <PublicTemplate
71+
template={timeCellTemplate}
72+
templateProps={{
73+
data: {
74+
date: startDate,
75+
text,
76+
groups,
77+
groupIndex,
78+
},
79+
index,
80+
} as DateTimeCellTemplateProps}
81+
/>}
82+
{!isTimeCellTemplate
83+
&& <PublicTemplate
84+
template={dateCellTemplate}
85+
templateProps={{
86+
data: {
87+
date: startDate,
88+
text,
89+
groups,
90+
groupIndex,
91+
},
92+
index,
93+
} as DateTimeCellTemplateProps}
94+
/>}
8995
</>
9096
)
9197
: (

packages/devextreme/js/__internal/scheduler/r1/components/base/date_table.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import type { InfernoEffect } from '@ts/core/r1/runtime/inferno/index';
22
import { createReRenderEffect, InfernoWrapperComponent } from '@ts/core/r1/runtime/inferno/index';
33
import type { JSXTemplate, RefObject } from '@ts/core/r1/types';
4-
import { getTemplate } from '@ts/core/r1/utils/index';
54

65
import type { CellTemplateProps, DefaultProps } from '../types';
76
import { DateTableBody, DateTableBodyDefaultProps } from './date_table_body';
@@ -44,8 +43,6 @@ export class DateTable extends InfernoWrapperComponent<DateTableProps> {
4443
const leftVirtualCellWidth = viewData.leftVirtualCellWidth ?? 0;
4544
const rightVirtualCellWidth = viewData.rightVirtualCellWidth ?? 0;
4645
const virtualCellsCount = viewData.groupedData[0].dateTable[0].cells.length;
47-
const CellTemplateComponent = getTemplate(cellTemplate);
48-
const DataCellTemplateComponent = getTemplate(dataCellTemplate);
4946

5047
return (
5148
<Table
@@ -64,8 +61,8 @@ export class DateTable extends InfernoWrapperComponent<DateTableProps> {
6461
<DateTableBody
6562
viewData={viewData}
6663
viewContext={viewContext}
67-
cellTemplate={CellTemplateComponent}
68-
dataCellTemplate={DataCellTemplateComponent}
64+
cellTemplate={cellTemplate}
65+
dataCellTemplate={dataCellTemplate}
6966
leftVirtualCellWidth={leftVirtualCellWidth}
7067
rightVirtualCellWidth={rightVirtualCellWidth}
7168
groupOrientation={groupOrientation}

packages/devextreme/js/__internal/scheduler/r1/components/base/date_table_body.tsx

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { BaseInfernoComponent } from '@ts/core/r1/runtime/inferno/index';
22
import type { JSXTemplate } from '@ts/core/r1/types';
3-
import { getTemplate } from '@ts/core/r1/utils/index';
3+
import { PublicTemplate } from '@ts/scheduler/r1/components/templates/index';
44
import { Fragment } from 'inferno';
55

66
import { combineClasses } from '../../../../core/r1/utils/render_utils';
@@ -34,8 +34,6 @@ export class DateTableBody extends BaseInfernoComponent<DateTableBodyProps> {
3434
[DATE_TABLE_ROW_CLASS]: true,
3535
'dx-scheduler-cell-sizes-vertical': addVerticalSizesClassToRows,
3636
});
37-
const CellTemplateComponent = getTemplate(cellTemplate);
38-
const DataCellTemplateComponent = getTemplate(dataCellTemplate);
3937

4038
return (
4139
<>
@@ -51,7 +49,7 @@ export class DateTableBody extends BaseInfernoComponent<DateTableBodyProps> {
5149
isGroupedAllDayPanel && <AllDayPanelTableBody
5250
viewData={allDayPanel ?? AllDayPanelTableBodyDefaultProps.viewData}
5351
viewContext={viewContext}
54-
dataCellTemplate={DataCellTemplateComponent}
52+
dataCellTemplate={dataCellTemplate}
5553
isVerticalGroupOrientation={true}
5654
leftVirtualCellWidth={viewData.leftVirtualCellWidth
5755
?? AllDayPanelTableBodyDefaultProps.leftVirtualCellWidth}
@@ -92,24 +90,26 @@ export class DateTableBody extends BaseInfernoComponent<DateTableBodyProps> {
9290
startDate,
9391
text,
9492
today,
95-
}) => CellTemplateComponent({
96-
key: cellKey,
97-
viewContext,
98-
isFirstGroupCell,
99-
isLastGroupCell,
100-
startDate,
101-
endDate,
102-
groups,
103-
groupIndex: cellGroupIndex,
104-
index: cellIndex,
105-
dataCellTemplate: DataCellTemplateComponent,
106-
text,
107-
today,
108-
otherMonth,
109-
firstDayOfMonth,
110-
isSelected,
111-
isFocused,
112-
}))
93+
}) => <PublicTemplate
94+
template={cellTemplate}
95+
templateProps={{
96+
key: cellKey,
97+
viewContext,
98+
isFirstGroupCell,
99+
isLastGroupCell,
100+
startDate,
101+
endDate,
102+
groups,
103+
groupIndex: cellGroupIndex,
104+
index: cellIndex,
105+
dataCellTemplate,
106+
text,
107+
today,
108+
otherMonth,
109+
firstDayOfMonth,
110+
isSelected,
111+
isFocused,
112+
} as CellTemplateProps} />)
113113
}
114114
</Row>
115115
))

packages/devextreme/js/__internal/scheduler/r1/components/base/date_table_cell_base.tsx

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { BaseInfernoComponent } from '@ts/core/r1/runtime/inferno/index';
22
import type { JSXTemplate } from '@ts/core/r1/types';
3-
import { getTemplate } from '@ts/core/r1/utils/index';
3+
import { PublicTemplate } from '@ts/scheduler/r1/components/templates/index';
44

55
import { combineClasses } from '../../../../core/r1/utils/render_utils';
66
import { renderUtils } from '../../utils/index';
@@ -104,7 +104,6 @@ export class DateTableCellBase extends BaseInfernoComponent<DateTableCellBasePro
104104
});
105105
const ariaLabel = isSelected ? ADD_APPOINTMENT_LABEL : undefined;
106106
const dataCellTemplateProps = this.getDataCellTemplateProps();
107-
const DataCellTemplateComponent = getTemplate(dataCellTemplate);
108107

109108
return (
110109
<CellBase
@@ -119,13 +118,14 @@ export class DateTableCellBase extends BaseInfernoComponent<DateTableCellBasePro
119118
>
120119
<>
121120
{
122-
!DataCellTemplateComponent && children
123-
}
124-
{
125-
!!DataCellTemplateComponent && DataCellTemplateComponent({
126-
index: dataCellTemplateProps.index,
127-
data: dataCellTemplateProps.data,
128-
})
121+
dataCellTemplate
122+
? <PublicTemplate
123+
template={dataCellTemplate}
124+
templateProps={{
125+
index: dataCellTemplateProps.index,
126+
data: dataCellTemplateProps.data,
127+
}} />
128+
: children
129129
}
130130
</>
131131
</CellBase>

packages/devextreme/js/__internal/scheduler/r1/components/base/group_panel.tsx

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import type { InfernoEffect } from '@ts/core/r1/runtime/inferno/index';
22
import { createReRenderEffect, InfernoWrapperComponent } from '@ts/core/r1/runtime/inferno/index';
33
import type { RefObject } from '@ts/core/r1/types';
4-
import { getTemplate } from '@ts/core/r1/utils/index';
54

65
import { VERTICAL_GROUP_ORIENTATION } from '../../const';
76
import type { Group, GroupOrientation } from '../../types';
@@ -41,9 +40,6 @@ export class GroupPanel extends InfernoWrapperComponent<GroupPanelProps> {
4140
groups,
4241
styles,
4342
} = this.props;
44-
const ResourceCellTemplateComponent = getTemplate(
45-
resourceCellTemplate,
46-
);
4743
const isVerticalLayout = isVerticalGroupingApplied(groups, groupOrientation);
4844

4945
const Layout = isVerticalLayout ? GroupPanelVertical : GroupPanelHorizontal;
@@ -52,7 +48,7 @@ export class GroupPanel extends InfernoWrapperComponent<GroupPanelProps> {
5248
<Layout
5349
viewContext={viewContext}
5450
height={height}
55-
resourceCellTemplate={ResourceCellTemplateComponent}
51+
resourceCellTemplate={resourceCellTemplate}
5652
className={className}
5753
groupPanelData={groupPanelData}
5854
elementRef={elementRef}

0 commit comments

Comments
 (0)