Skip to content

Commit ee2ff0e

Browse files
authored
Scheduler: fix options updating on view change (T1297019, T1301345) (#30504)
Co-authored-by: Vladimir Bushmanov <[email protected]>
1 parent 9758039 commit ee2ff0e

File tree

7 files changed

+150
-68
lines changed

7 files changed

+150
-68
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import Scheduler from '@ts/scheduler/m_scheduler';
2+
3+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
4+
type Config = any;
5+
6+
export const createScheduler = async (config: Config): Promise<{
7+
container: HTMLDivElement;
8+
scheduler: Scheduler;
9+
}> => {
10+
const container = document.createElement('div');
11+
const scheduler = new Scheduler(container, config);
12+
await new Promise(process.nextTick);
13+
14+
return {
15+
container,
16+
scheduler,
17+
};
18+
};

packages/devextreme/js/__internal/scheduler/__tests__/__mock__/m_mock_scheduler.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,12 @@ import DOMComponent from '@ts/core/widget/dom_component';
33

44
import SchedulerWorkSpace from '../../workspaces/m_work_space';
55

6-
export const setupSchedulerTestEnvironment = ({
7-
cellWidth,
8-
cellHeight,
9-
} = {
10-
cellWidth: 250,
11-
cellHeight: 80,
12-
}): void => {
6+
export const setupSchedulerTestEnvironment = (
7+
isTimelineView = false,
8+
): void => {
9+
const cellWidth = 250;
10+
const cellHeight = isTimelineView ? 450 : 80;
11+
1312
(DOMComponent.prototype as any)._isVisible = jest.fn().mockReturnValue(true);
1413
SchedulerWorkSpace.prototype._createCrossScrollingConfig = () => ({
1514
direction: 'both',

packages/devextreme/js/__internal/scheduler/__tests__/performance.test.ts

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
/* eslint-disable @typescript-eslint/no-unused-vars */
21
import {
32
beforeEach, describe, expect, it, jest,
43
} from '@jest/globals';
54

6-
import Scheduler from '../m_scheduler';
75
import timezoneUtils from '../m_utils_time_zone';
6+
import { createScheduler } from './__mock__/create_scheduler';
87

98
const startDate = new Date(2025, 0, 6);
109
const delta = 15 * 60 * 1000;
@@ -15,8 +14,7 @@ const dataSource = Array.from({ length: 10 }, (_, i) => ({
1514
text: `Appointment ${i + 1}`,
1615
}));
1716

18-
// TODO: fix during T1297019
19-
describe.skip('scheduler', () => {
17+
describe('scheduler', () => {
2018
beforeEach(() => {
2119
jest.clearAllMocks();
2220
});
@@ -25,8 +23,7 @@ describe.skip('scheduler', () => {
2523
{ timeZone: 'Europe/London' },
2624
{ timeZone: undefined },
2725
])('should memo Intl object for timezone: $timeZone', async ({ timeZone }) => {
28-
const container = document.createElement('div');
29-
const scheduler = new Scheduler(container, {
26+
const { container } = await createScheduler({
3027
dataSource,
3128
timeZone,
3229
views: ['week'],
@@ -35,7 +32,7 @@ describe.skip('scheduler', () => {
3532
startDayHour: 8,
3633
firstDayOfWeek: 1,
3734
height: 600,
38-
} as any);
35+
});
3936
await timezoneUtils.cacheTimeZones();
4037

4138
expect(container.classList).toContain('dx-scheduler');
@@ -49,6 +46,6 @@ describe.skip('scheduler', () => {
4946
nextButton.click();
5047
expect(navigator.querySelector('.dx-scheduler-navigator-caption')?.textContent).toBe('20-26 January 2025');
5148

52-
expect(Intl.DateTimeFormat).toHaveBeenCalledTimes(0);
49+
expect(Intl.DateTimeFormat).toHaveBeenCalledTimes(timeZone ? 0 : 1);
5350
});
5451
});
Lines changed: 77 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
/* eslint-disable @typescript-eslint/no-unused-vars */
2-
31
import {
42
describe, expect, it,
53
} from '@jest/globals';
64
import { DataSource } from '@ts/data/data_source/m_data_source';
75
import CustomStore from '@ts/data/m_custom_store';
6+
import { createScheduler } from '@ts/scheduler/__tests__/__mock__/create_scheduler';
87

9-
import Scheduler from '../m_scheduler';
108
import { setupSchedulerTestEnvironment } from './__mock__/m_mock_scheduler';
119

1210
const dataSource = [
@@ -21,58 +19,95 @@ const dataSource = [
2119
const rooms = [
2220
{ id: 1, text: 'Room 2', color: 'rgb(142, 205, 60)' },
2321
];
22+
const rooms2 = [
23+
{ id: 1, text: 'Room 2', color: 'rgb(60, 154, 205)' },
24+
];
2425
const getAppointmentColor = (container: HTMLDivElement): string => {
2526
const appointment = container.querySelector('.dx-scheduler-appointment') as HTMLDivElement;
2627
return appointment.style.backgroundColor;
2728
};
29+
const getAgendaAppointmentColor = (container: HTMLDivElement): string => {
30+
const appointment = container.querySelector('.dx-scheduler-agenda-appointment-marker') as HTMLDivElement;
31+
return appointment.style.backgroundColor;
32+
};
2833

2934
describe('Resources', () => {
30-
it('should render correct appointment color for remote datasource (T1300252)', async () => {
31-
setupSchedulerTestEnvironment();
35+
describe.each([
36+
'month',
37+
'agenda',
38+
])('%s view', (view) => {
39+
const getColor = view === 'agenda'
40+
? getAgendaAppointmentColor
41+
: getAppointmentColor;
3242

33-
const dataPromise = new Promise((resolve) => {
34-
setTimeout(resolve, 100, rooms);
35-
});
36-
const container = document.createElement('div');
37-
const scheduler = new Scheduler(container, {
38-
views: ['month'],
39-
currentView: 'month',
40-
currentDate: new Date(2024, 8, 8),
41-
dataSource,
42-
resources: [{
43-
fieldExpr: 'roomId',
44-
label: 'Room',
45-
dataSource: new DataSource({
46-
store: new CustomStore({
47-
load: () => dataPromise,
43+
it('should render correct appointment color for remote datasource (T1300252)', async () => {
44+
setupSchedulerTestEnvironment();
45+
46+
const dataPromise = new Promise((resolve) => {
47+
setTimeout(resolve, 100, rooms);
48+
});
49+
const { container } = await createScheduler({
50+
views: [view],
51+
currentView: view,
52+
currentDate: new Date(2024, 8, 7),
53+
dataSource,
54+
resources: [{
55+
fieldExpr: 'roomId',
56+
label: 'Room',
57+
dataSource: new DataSource({
58+
store: new CustomStore({
59+
load: () => dataPromise,
60+
}),
61+
paginate: false,
4862
}),
49-
paginate: false,
50-
}),
51-
}],
52-
} as any);
53-
await dataPromise;
54-
await new Promise(process.nextTick);
63+
}],
64+
});
65+
await dataPromise;
66+
await new Promise(process.nextTick);
5567

56-
expect(getAppointmentColor(container)).toBe(rooms[0].color);
57-
});
68+
expect(getColor(container)).toBe(rooms[0].color);
69+
});
5870

59-
it('should render correct appointment color for local datasource (T1300252)', async () => {
60-
setupSchedulerTestEnvironment();
71+
it('should render correct appointment color for local datasource (T1300252)', async () => {
72+
setupSchedulerTestEnvironment();
6173

62-
const container = document.createElement('div');
63-
const scheduler = new Scheduler(container, {
64-
views: ['month'],
65-
currentView: 'month',
66-
currentDate: new Date(2024, 8, 8),
67-
dataSource,
68-
resources: [{
74+
const { container } = await createScheduler({
75+
views: [view],
76+
currentView: view,
77+
currentDate: new Date(2024, 8, 7),
78+
dataSource,
79+
resources: [{
80+
fieldExpr: 'roomId',
81+
label: 'Room',
82+
dataSource: rooms,
83+
}],
84+
});
85+
86+
expect(getColor(container)).toBe(rooms[0].color);
87+
});
88+
89+
it('should render appointments after resources update (T1301345)', async () => {
90+
setupSchedulerTestEnvironment();
91+
92+
const { container, scheduler } = await createScheduler({
93+
views: [view],
94+
currentView: view,
95+
currentDate: new Date(2024, 8, 7),
96+
dataSource,
97+
resources: [{
98+
fieldExpr: 'roomId',
99+
label: 'Room',
100+
dataSource: rooms,
101+
}],
102+
});
103+
scheduler.option('resources', [{
69104
fieldExpr: 'roomId',
70105
label: 'Room',
71-
dataSource: rooms,
72-
}],
73-
} as any);
74-
await new Promise(process.nextTick);
106+
dataSource: rooms2,
107+
}]);
108+
await new Promise(process.nextTick);
75109

76-
expect(getAppointmentColor(container)).toBe(rooms[0].color);
110+
expect(getColor(container)).toBe(rooms2[0].color);
111+
});
77112
});
78113
});

packages/devextreme/js/__internal/scheduler/__tests__/santiago_timezone.test.ts

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
/**
22
* @timezone America/Santiago
33
*/
4-
/* eslint-disable @typescript-eslint/no-unused-vars */
54

65
import {
76
describe, expect, it,
87
} from '@jest/globals';
98

10-
import Scheduler from '../m_scheduler';
9+
import { createScheduler } from './__mock__/create_scheduler';
1110
import { setupSchedulerTestEnvironment } from './__mock__/m_mock_scheduler';
1211

1312
const dataSource = [
@@ -104,22 +103,17 @@ const getTexts = (
104103

105104
describe('scheduler', () => {
106105
it.each(views)('should render correct workspace in Santiago DST for view: $view.name', async ({ view, result }) => {
107-
setupSchedulerTestEnvironment({
108-
cellWidth: 250,
109-
cellHeight: view.name.includes('Timeline') ? 450 : 80,
110-
});
106+
setupSchedulerTestEnvironment(true);
111107

112-
const container = document.createElement('div');
113-
const scheduler = new Scheduler(container, {
108+
const { container } = await createScheduler({
114109
views: [view],
115110
currentView: view.name,
116111
currentDate: new Date(2024, 8, 8),
117112
height: 600,
118113
cellDuration: 60,
119114
firstDayOfWeek: 1,
120115
dataSource,
121-
} as any);
122-
await new Promise(process.nextTick);
116+
});
123117

124118
if (result.hasCellContent) {
125119
const cells = container.querySelectorAll('.dx-scheduler-date-table-cell');
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import {
2+
describe, expect, it,
3+
} from '@jest/globals';
4+
5+
import { createScheduler } from './__mock__/create_scheduler';
6+
import { setupSchedulerTestEnvironment } from './__mock__/m_mock_scheduler';
7+
8+
describe('views', () => {
9+
it('should render appointment after view change (T1297019)', async () => {
10+
setupSchedulerTestEnvironment();
11+
const { container, scheduler } = await createScheduler({
12+
timeZone: 'Etc/UTC',
13+
dataSource: [{
14+
text: 'Appointment',
15+
startDate: new Date('2021-02-02T08:00:00.000Z'),
16+
endDate: new Date('2021-02-02T20:00:00.000Z'),
17+
allDay: true,
18+
}],
19+
views: [{
20+
type: 'day',
21+
allDayPanelMode: 'hidden',
22+
}, {
23+
allDayPanelMode: 'all',
24+
type: 'timelineDay',
25+
}],
26+
currentView: 'timelineDay',
27+
currentDate: new Date('2021-02-02T10:00:00.000Z'),
28+
startDayHour: 8,
29+
endDayHour: 20,
30+
showAllDayPanel: false,
31+
height: 730,
32+
});
33+
34+
scheduler.option('currentView', 'day');
35+
await new Promise(process.nextTick);
36+
37+
const appointment = container.querySelector('.dx-scheduler-appointment');
38+
expect(appointment !== null).toBe(true);
39+
});
40+
});

packages/devextreme/js/__internal/scheduler/m_scheduler.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -767,7 +767,6 @@ class Scheduler extends SchedulerOptionsBaseWidget {
767767
allDayPanelMode: () => this.getViewOption('allDayPanelMode'),
768768
showAllDayPanel: () => this.option('showAllDayPanel'),
769769
getResourceManager: () => this.resourceManager,
770-
getLoadedResources: () => this.option('loadedResources'),
771770
getIsVirtualScrolling: () => this.isVirtualScrolling(),
772771
getSupportAllDayRow: () => this._workSpace.supportAllDayRow(),
773772
getViewType: () => this._workSpace.type,

0 commit comments

Comments
 (0)