Skip to content

Commit a33780b

Browse files
Scheduler - Move scroll position update from Popup to Scheduler (#33322)
1 parent 22f9e5f commit a33780b

File tree

4 files changed

+52
-36
lines changed

4 files changed

+52
-36
lines changed

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ interface CreateAppointmentPopupResult {
7777
addAppointment: jest.Mock;
7878
updateAppointment: jest.Mock;
7979
focus: jest.Mock;
80-
updateScrollPosition: jest.Mock;
8180
onSave: jest.Mock<(appointment: Record<string, unknown>) => PromiseLike<unknown>>;
8281
};
8382
dispose: () => void;
@@ -112,7 +111,6 @@ export const createAppointmentPopup = async (
112111
const updateAppointment = options.updateAppointment
113112
?? jest.fn(resolvedDeferred);
114113
const focus = jest.fn();
115-
const updateScrollPosition = jest.fn();
116114
const onSave = options.onSave
117115
?? jest.fn<(appointment: Record<string, unknown>) => PromiseLike<unknown>>(resolvedDeferred);
118116

@@ -157,7 +155,6 @@ export const createAppointmentPopup = async (
157155
},
158156
addAppointment,
159157
updateAppointment,
160-
updateScrollPosition,
161158
};
162159

163160
const popup = new AppointmentPopup(popupSchedulerProxy, form);
@@ -199,7 +196,6 @@ export const createAppointmentPopup = async (
199196
addAppointment,
200197
updateAppointment,
201198
focus,
202-
updateScrollPosition,
203199
onSave,
204200
},
205201
dispose,

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,29 @@ describe('Scheduler scrollTo', () => {
9191
expect(loggerWarnSpy).toHaveBeenCalledTimes(0);
9292
});
9393

94+
it('should scroll to appointment position after saving from popup', async () => {
95+
const { container, scheduler, POM } = await createScheduler({
96+
dataSource: [{
97+
text: 'Late appointment',
98+
startDate: new Date(2017, 4, 25, 22, 0),
99+
endDate: new Date(2017, 4, 25, 23, 0),
100+
}],
101+
views: ['timelineDay'],
102+
currentView: 'timelineDay',
103+
currentDate: new Date(2017, 4, 25),
104+
});
105+
const scrollableElement = container.querySelector('.dx-scheduler-date-table-scrollable') as HTMLElement;
106+
const scrollableContainer = scrollableElement.querySelector('.dx-scrollable-container') as HTMLElement;
107+
const scrollLeftBeforeSave = scrollableContainer.scrollLeft;
108+
109+
const item = (scheduler as any).getDataSource().items()[0];
110+
scheduler.showAppointmentPopup(item);
111+
POM.popup.saveButton.click();
112+
113+
expect(scrollLeftBeforeSave).toBe(0);
114+
expect(scrollableContainer.scrollLeft).toBeGreaterThan(0);
115+
});
116+
94117
it('should pass different left offsets for "start" vs "center" alignInView', async () => {
95118
const { container, scheduler } = await createScheduler({
96119
dataSource: [],

packages/devextreme/js/__internal/scheduler/appointment_popup/m_popup.ts

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,13 @@ import { current, isFluent } from '@js/ui/themes';
1515
import { hide as hideLoading, show as showLoading } from '../m_loading';
1616
import type { SafeAppointment } from '../types';
1717
import { AppointmentAdapter } from '../utils/appointment_adapter/appointment_adapter';
18-
import { getAppointmentGroupValues, getRawAppointmentGroupValues } from '../utils/resource_manager/appointment_groups_utils';
18+
import { getRawAppointmentGroupValues } from '../utils/resource_manager/appointment_groups_utils';
1919
import type { AppointmentForm } from './m_form';
2020

2121
export const APPOINTMENT_POPUP_CLASS = 'dx-scheduler-appointment-popup';
2222

2323
const POPUP_FULL_SCREEN_MODE_WINDOW_WIDTH_THRESHOLD = 485;
2424

25-
const DAY_IN_MS = dateUtils.dateToMilliseconds('day');
26-
2725
export interface AppointmentPopupConfig {
2826
onSave: (appointment: Record<string, unknown>) => PromiseLike<unknown>;
2927
title: string;
@@ -61,7 +59,6 @@ export class AppointmentPopup {
6159
this.form = form;
6260

6361
this.state = {
64-
lastEditData: null,
6562
saveChangesLocker: false,
6663
appointment: {
6764
data: null,
@@ -282,7 +279,6 @@ export class AppointmentPopup {
282279

283280
deferred.done(() => {
284281
hideLoading();
285-
this.state.lastEditData = appointment;
286282
});
287283
});
288284

@@ -300,27 +296,7 @@ export class AppointmentPopup {
300296

301297
if (this.tryLockSaveChanges()) {
302298
when(this.saveChangesAsync(true)).done(() => {
303-
if (this.state.lastEditData) { // TODO
304-
const adapter = this.createAppointmentAdapter(this.state.lastEditData);
305-
306-
const { startDate, endDate, allDay } = adapter;
307-
308-
const startTime = startDate.getTime();
309-
const endTime = endDate.getTime();
310-
311-
const inAllDayRow = allDay || (endTime - startTime) >= DAY_IN_MS;
312-
const resourceManager = this.scheduler.getResourceManager();
313-
const appointmentGroupValues = getAppointmentGroupValues(
314-
this.state.lastEditData,
315-
resourceManager.resources,
316-
);
317-
318-
this.scheduler.updateScrollPosition(startDate, appointmentGroupValues, inAllDayRow);
319-
this.state.lastEditData = null;
320-
}
321-
322299
this.unlockSaveChanges();
323-
324300
deferred.resolve();
325301
});
326302
}

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

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ import { macroTaskArray } from './utils/index';
7878
import { isAgendaWorkspaceComponent } from './utils/is_agenda_workpace_component';
7979
import { VIEWS } from './utils/options/constants_view';
8080
import type { NormalizedView } from './utils/options/types';
81-
import { setAppointmentGroupValues } from './utils/resource_manager/appointment_groups_utils';
81+
import { getAppointmentGroupValues, setAppointmentGroupValues } from './utils/resource_manager/appointment_groups_utils';
8282
import { ResourceManager } from './utils/resource_manager/resource_manager';
8383
import AppointmentLayoutManager from './view_model/appointments_layout_manager';
8484
import { AppointmentDataSource } from './view_model/m_appointment_data_source';
@@ -1169,13 +1169,31 @@ class Scheduler extends SchedulerOptionsBaseWidget {
11691169
addAppointment: (appointment) => this.addAppointment(appointment),
11701170
updateAppointment: (sourceAppointment, updatedAppointment) => this.updateAppointment(sourceAppointment, updatedAppointment),
11711171

1172-
updateScrollPosition: (startDate, appointmentGroupValues, inAllDayRow) => {
1173-
this._workSpace.updateScrollPosition(startDate, appointmentGroupValues, inAllDayRow);
1174-
},
11751172
};
11761173
return new AppointmentPopup(scheduler, form);
11771174
}
11781175

1176+
private scrollToAppointment(appointment: Record<string, unknown>): void {
1177+
const adapter = new AppointmentAdapter(appointment, this._dataAccessors);
1178+
const { startDate, endDate, allDay } = adapter;
1179+
1180+
if (!startDate) {
1181+
return;
1182+
}
1183+
1184+
const startTime = startDate.getTime();
1185+
const endTime = endDate ? endDate.getTime() : startTime;
1186+
const dayInMs = toMs('day');
1187+
1188+
const inAllDayRow = allDay || (endTime - startTime) >= dayInMs;
1189+
const appointmentGroupValues = getAppointmentGroupValues(
1190+
appointment,
1191+
this.resourceManager.resources,
1192+
);
1193+
1194+
this._workSpace.updateScrollPosition(startDate, appointmentGroupValues, inAllDayRow);
1195+
}
1196+
11791197
private getAppointmentTooltipOptions() {
11801198
const that = this;
11811199
return {
@@ -1638,7 +1656,8 @@ class Scheduler extends SchedulerOptionsBaseWidget {
16381656
this.appointmentPopup.show(singleRawAppointment, {
16391657
onSave: (newAppointment) => {
16401658
this.updateAppointment(rawAppointment, appointment.source);
1641-
return this.addAppointment(newAppointment);
1659+
return when(this.addAppointment(newAppointment))
1660+
.done(() => this.scrollToAppointment(newAppointment));
16421661
},
16431662
title: messageLocalization.format('dxScheduler-editPopupTitle'),
16441663
readOnly: Boolean(appointment.source) && appointment.disabled,
@@ -2012,7 +2031,8 @@ class Scheduler extends SchedulerOptionsBaseWidget {
20122031
delete this.editAppointmentData; // TODO
20132032
if (this.editing.allowAdding) {
20142033
this.appointmentPopup.show(rawAppointment, {
2015-
onSave: (appointment) => this.addAppointment(appointment),
2034+
onSave: (appointment) => when(this.addAppointment(appointment))
2035+
.done(() => this.scrollToAppointment(appointment)),
20162036
title: messageLocalization.format('dxScheduler-newPopupTitle'),
20172037
readOnly: false,
20182038
});
@@ -2028,7 +2048,8 @@ class Scheduler extends SchedulerOptionsBaseWidget {
20282048
const readOnly = isDisabled || !this.editing.allowUpdating;
20292049

20302050
this.appointmentPopup.show(rawAppointment, {
2031-
onSave: (appointment) => this.updateAppointment(rawAppointment, appointment),
2051+
onSave: (appointment) => when(this.updateAppointment(rawAppointment, appointment))
2052+
.done(() => this.scrollToAppointment(appointment)),
20322053
title: messageLocalization.format('dxScheduler-editPopupTitle'),
20332054
readOnly,
20342055
});

0 commit comments

Comments
 (0)