Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ interface CreateAppointmentPopupResult {
addAppointment: jest.Mock;
updateAppointment: jest.Mock;
focus: jest.Mock;
updateScrollPosition: jest.Mock;
onSave: jest.Mock<(appointment: Record<string, unknown>) => PromiseLike<unknown>>;
};
dispose: () => void;
Expand Down Expand Up @@ -112,7 +111,6 @@ export const createAppointmentPopup = async (
const updateAppointment = options.updateAppointment
?? jest.fn(resolvedDeferred);
const focus = jest.fn();
const updateScrollPosition = jest.fn();
const onSave = options.onSave
?? jest.fn<(appointment: Record<string, unknown>) => PromiseLike<unknown>>(resolvedDeferred);

Expand Down Expand Up @@ -157,7 +155,6 @@ export const createAppointmentPopup = async (
},
addAppointment,
updateAppointment,
updateScrollPosition,
};

const popup = new AppointmentPopup(popupSchedulerProxy, form);
Expand Down Expand Up @@ -199,7 +196,6 @@ export const createAppointmentPopup = async (
addAppointment,
updateAppointment,
focus,
updateScrollPosition,
onSave,
},
dispose,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,29 @@ describe('Scheduler scrollTo', () => {
expect(loggerWarnSpy).toHaveBeenCalledTimes(0);
});

it('should scroll to appointment position after saving from popup', async () => {
const { container, scheduler, POM } = await createScheduler({
dataSource: [{
text: 'Late appointment',
startDate: new Date(2017, 4, 25, 22, 0),
endDate: new Date(2017, 4, 25, 23, 0),
}],
views: ['timelineDay'],
currentView: 'timelineDay',
currentDate: new Date(2017, 4, 25),
});
const scrollableElement = container.querySelector('.dx-scheduler-date-table-scrollable') as HTMLElement;
const scrollableContainer = scrollableElement.querySelector('.dx-scrollable-container') as HTMLElement;
const scrollLeftBeforeSave = scrollableContainer.scrollLeft;

const item = (scheduler as any).getDataSource().items()[0];
scheduler.showAppointmentPopup(item);
POM.popup.saveButton.click();

expect(scrollLeftBeforeSave).toBe(0);
expect(scrollableContainer.scrollLeft).toBeGreaterThan(0);
});

it('should pass different left offsets for "start" vs "center" alignInView', async () => {
const { container, scheduler } = await createScheduler({
dataSource: [],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,13 @@ import { current, isFluent } from '@js/ui/themes';
import { hide as hideLoading, show as showLoading } from '../m_loading';
import type { SafeAppointment } from '../types';
import { AppointmentAdapter } from '../utils/appointment_adapter/appointment_adapter';
import { getAppointmentGroupValues, getRawAppointmentGroupValues } from '../utils/resource_manager/appointment_groups_utils';
import { getRawAppointmentGroupValues } from '../utils/resource_manager/appointment_groups_utils';
import type { AppointmentForm } from './m_form';

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

const POPUP_FULL_SCREEN_MODE_WINDOW_WIDTH_THRESHOLD = 485;

const DAY_IN_MS = dateUtils.dateToMilliseconds('day');

export interface AppointmentPopupConfig {
onSave: (appointment: Record<string, unknown>) => PromiseLike<unknown>;
title: string;
Expand Down Expand Up @@ -61,7 +59,6 @@ export class AppointmentPopup {
this.form = form;

this.state = {
lastEditData: null,
saveChangesLocker: false,
appointment: {
data: null,
Expand Down Expand Up @@ -282,7 +279,6 @@ export class AppointmentPopup {

deferred.done(() => {
hideLoading();
this.state.lastEditData = appointment;
});
});

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

if (this.tryLockSaveChanges()) {
when(this.saveChangesAsync(true)).done(() => {
if (this.state.lastEditData) { // TODO
const adapter = this.createAppointmentAdapter(this.state.lastEditData);

const { startDate, endDate, allDay } = adapter;

const startTime = startDate.getTime();
const endTime = endDate.getTime();

const inAllDayRow = allDay || (endTime - startTime) >= DAY_IN_MS;
const resourceManager = this.scheduler.getResourceManager();
const appointmentGroupValues = getAppointmentGroupValues(
this.state.lastEditData,
resourceManager.resources,
);

this.scheduler.updateScrollPosition(startDate, appointmentGroupValues, inAllDayRow);
this.state.lastEditData = null;
}

this.unlockSaveChanges();

deferred.resolve();
});
}
Expand Down
35 changes: 28 additions & 7 deletions packages/devextreme/js/__internal/scheduler/m_scheduler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ import { macroTaskArray } from './utils/index';
import { isAgendaWorkspaceComponent } from './utils/is_agenda_workpace_component';
import { VIEWS } from './utils/options/constants_view';
import type { NormalizedView } from './utils/options/types';
import { setAppointmentGroupValues } from './utils/resource_manager/appointment_groups_utils';
import { getAppointmentGroupValues, setAppointmentGroupValues } from './utils/resource_manager/appointment_groups_utils';
import { ResourceManager } from './utils/resource_manager/resource_manager';
import AppointmentLayoutManager from './view_model/appointments_layout_manager';
import { AppointmentDataSource } from './view_model/m_appointment_data_source';
Expand Down Expand Up @@ -1169,13 +1169,31 @@ class Scheduler extends SchedulerOptionsBaseWidget {
addAppointment: (appointment) => this.addAppointment(appointment),
updateAppointment: (sourceAppointment, updatedAppointment) => this.updateAppointment(sourceAppointment, updatedAppointment),

updateScrollPosition: (startDate, appointmentGroupValues, inAllDayRow) => {
this._workSpace.updateScrollPosition(startDate, appointmentGroupValues, inAllDayRow);
},
};
return new AppointmentPopup(scheduler, form);
}

private scrollToAppointment(appointment: Record<string, unknown>): void {
const adapter = new AppointmentAdapter(appointment, this._dataAccessors);
const { startDate, endDate, allDay } = adapter;

if (!startDate) {
return;
}

const startTime = startDate.getTime();
const endTime = endDate ? endDate.getTime() : startTime;
const dayInMs = toMs('day');

const inAllDayRow = allDay || (endTime - startTime) >= dayInMs;
const appointmentGroupValues = getAppointmentGroupValues(
appointment,
this.resourceManager.resources,
);

this._workSpace.updateScrollPosition(startDate, appointmentGroupValues, inAllDayRow);
}

private getAppointmentTooltipOptions() {
const that = this;
return {
Expand Down Expand Up @@ -1638,7 +1656,8 @@ class Scheduler extends SchedulerOptionsBaseWidget {
this.appointmentPopup.show(singleRawAppointment, {
onSave: (newAppointment) => {
this.updateAppointment(rawAppointment, appointment.source);
return this.addAppointment(newAppointment);
return when(this.addAppointment(newAppointment))
.done(() => this.scrollToAppointment(newAppointment));
},
title: messageLocalization.format('dxScheduler-editPopupTitle'),
readOnly: Boolean(appointment.source) && appointment.disabled,
Expand Down Expand Up @@ -2012,7 +2031,8 @@ class Scheduler extends SchedulerOptionsBaseWidget {
delete this.editAppointmentData; // TODO
if (this.editing.allowAdding) {
this.appointmentPopup.show(rawAppointment, {
onSave: (appointment) => this.addAppointment(appointment),
onSave: (appointment) => when(this.addAppointment(appointment))
.done(() => this.scrollToAppointment(appointment)),
title: messageLocalization.format('dxScheduler-newPopupTitle'),
readOnly: false,
});
Expand All @@ -2028,7 +2048,8 @@ class Scheduler extends SchedulerOptionsBaseWidget {
const readOnly = isDisabled || !this.editing.allowUpdating;

this.appointmentPopup.show(rawAppointment, {
onSave: (appointment) => this.updateAppointment(rawAppointment, appointment),
onSave: (appointment) => when(this.updateAppointment(rawAppointment, appointment))
.done(() => this.scrollToAppointment(appointment)),
title: messageLocalization.format('dxScheduler-editPopupTitle'),
readOnly,
});
Expand Down
Loading