Skip to content

Commit e0c00a6

Browse files
Scheduler - Move scroll position update from Popup to Scheduler (#33313)
1 parent fbfef51 commit e0c00a6

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
@@ -78,7 +78,6 @@ interface CreateAppointmentPopupResult {
7878
addAppointment: jest.Mock;
7979
updateAppointment: jest.Mock;
8080
focus: jest.Mock;
81-
updateScrollPosition: jest.Mock;
8281
onSave: jest.Mock;
8382
};
8483
dispose: () => void;
@@ -113,7 +112,6 @@ export const createAppointmentPopup = async (
113112
const updateAppointment = options.updateAppointment
114113
?? jest.fn(resolvedDeferred);
115114
const focus = jest.fn();
116-
const updateScrollPosition = jest.fn();
117115
const onSave = options.onSave ?? jest.fn(resolvedDeferred);
118116

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

163160
const popup = new AppointmentPopup(popupSchedulerProxy, form);
@@ -203,7 +200,6 @@ export const createAppointmentPopup = async (
203200
addAppointment,
204201
updateAppointment,
205202
focus,
206-
updateScrollPosition,
207203
onSave,
208204
},
209205
dispose,

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

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

66+
it('should scroll to appointment position after saving from popup', async () => {
67+
const { container, scheduler, POM } = await createScheduler({
68+
dataSource: [{
69+
text: 'Late appointment',
70+
startDate: new Date(2017, 4, 25, 22, 0),
71+
endDate: new Date(2017, 4, 25, 23, 0),
72+
}],
73+
views: ['timelineDay'],
74+
currentView: 'timelineDay',
75+
currentDate: new Date(2017, 4, 25),
76+
});
77+
const scrollableElement = container.querySelector('.dx-scheduler-date-table-scrollable') as HTMLElement;
78+
const scrollableContainer = scrollableElement.querySelector('.dx-scrollable-container') as HTMLElement;
79+
const scrollLeftBeforeSave = scrollableContainer.scrollLeft;
80+
81+
const item = (scheduler as any).getDataSource().items()[0];
82+
scheduler.showAppointmentPopup(item);
83+
POM.popup.saveButton.click();
84+
85+
expect(scrollLeftBeforeSave).toBe(0);
86+
expect(scrollableContainer.scrollLeft).toBeGreaterThan(0);
87+
});
88+
6689
it('should pass different left offsets for "start" vs "center" alignInView', async () => {
6790
const { container, scheduler } = await createScheduler({
6891
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';
@@ -1157,13 +1157,31 @@ class Scheduler extends SchedulerOptionsBaseWidget {
11571157
addAppointment: (appointment) => this.addAppointment(appointment),
11581158
updateAppointment: (sourceAppointment, updatedAppointment) => this.updateAppointment(sourceAppointment, updatedAppointment),
11591159

1160-
updateScrollPosition: (startDate, appointmentGroupValues, inAllDayRow) => {
1161-
this._workSpace.updateScrollPosition(startDate, appointmentGroupValues, inAllDayRow);
1162-
},
11631160
};
11641161
return new AppointmentPopup(scheduler, form);
11651162
}
11661163

1164+
private scrollToAppointment(appointment: Record<string, unknown>): void {
1165+
const adapter = new AppointmentAdapter(appointment, this._dataAccessors);
1166+
const { startDate, endDate, allDay } = adapter;
1167+
1168+
if (!startDate) {
1169+
return;
1170+
}
1171+
1172+
const startTime = startDate.getTime();
1173+
const endTime = endDate ? endDate.getTime() : startTime;
1174+
const dayInMs = toMs('day');
1175+
1176+
const inAllDayRow = allDay || (endTime - startTime) >= dayInMs;
1177+
const appointmentGroupValues = getAppointmentGroupValues(
1178+
appointment,
1179+
this.resourceManager.resources,
1180+
);
1181+
1182+
this._workSpace.updateScrollPosition(startDate, appointmentGroupValues, inAllDayRow);
1183+
}
1184+
11671185
private getAppointmentTooltipOptions() {
11681186
const that = this;
11691187
return {
@@ -1623,7 +1641,8 @@ class Scheduler extends SchedulerOptionsBaseWidget {
16231641
this.appointmentPopup.show(singleRawAppointment, {
16241642
onSave: (newAppointment) => {
16251643
this.updateAppointment(rawAppointment, appointment.source);
1626-
return this.addAppointment(newAppointment);
1644+
return when(this.addAppointment(newAppointment))
1645+
.done(() => this.scrollToAppointment(newAppointment));
16271646
},
16281647
title: messageLocalization.format('dxScheduler-editPopupTitle'),
16291648
readOnly: Boolean(appointment.source) && appointment.disabled,
@@ -1997,7 +2016,8 @@ class Scheduler extends SchedulerOptionsBaseWidget {
19972016
delete this.editAppointmentData; // TODO
19982017
if (this.editing.allowAdding) {
19992018
this.appointmentPopup.show(rawAppointment, {
2000-
onSave: (appointment) => this.addAppointment(appointment),
2019+
onSave: (appointment) => when(this.addAppointment(appointment))
2020+
.done(() => this.scrollToAppointment(appointment)),
20012021
title: messageLocalization.format('dxScheduler-newPopupTitle'),
20022022
readOnly: false,
20032023
});
@@ -2013,7 +2033,8 @@ class Scheduler extends SchedulerOptionsBaseWidget {
20132033
const readOnly = isDisabled || !this.editing.allowUpdating;
20142034

20152035
this.appointmentPopup.show(rawAppointment, {
2016-
onSave: (appointment) => this.updateAppointment(rawAppointment, appointment),
2036+
onSave: (appointment) => when(this.updateAppointment(rawAppointment, appointment))
2037+
.done(() => this.scrollToAppointment(appointment)),
20172038
title: messageLocalization.format('dxScheduler-editPopupTitle'),
20182039
readOnly,
20192040
});

0 commit comments

Comments
 (0)