From 3ca4956735b13372efbdd254a1f8e6bd5b660884 Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Tue, 13 Jan 2026 12:38:02 +0100 Subject: [PATCH 1/8] test: fix bug --- .../m_compact_appointments_helper.ts | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/packages/devextreme/js/__internal/scheduler/m_compact_appointments_helper.ts b/packages/devextreme/js/__internal/scheduler/m_compact_appointments_helper.ts index f7c4ab825c3e..6adefc54f319 100644 --- a/packages/devextreme/js/__internal/scheduler/m_compact_appointments_helper.ts +++ b/packages/devextreme/js/__internal/scheduler/m_compact_appointments_helper.ts @@ -127,7 +127,10 @@ export class CompactAppointmentsHelper { _createCompactButtonElement({ isCompact, $container, coordinates, sortedIndex, items, }: CompactAppointmentOptions) { - const appointmentDate = this._getDateText(items[0].appointment); + const appointmentDate = this._getDateText( + items[0].appointment, + items[0].targetedAppointment, + ); const result = $('
') .addClass(APPOINTMENT_COLLECTOR_CLASS) .attr('aria-roledescription', appointmentDate) @@ -187,16 +190,18 @@ export class CompactAppointmentsHelper { return date ? new Date(date) : null; } - _getDateText(appointment) { - const startDate = this.instance._dataAccessors.get('startDate', appointment); - const endDate = this.instance._dataAccessors.get('endDate', appointment); + _getDateText(appointment, targetedAppointment?) { + const displayStartDate = targetedAppointment?.displayStartDate; + const displayEndDate = targetedAppointment?.displayEndDate; + + const startDate = displayStartDate || this._getStartDate(appointment); + const endDate = displayEndDate || this._getEndDate(appointment); + const startDateText = startDate ? this._localizeDate(startDate) : ''; const endDateText = endDate ? this._localizeDate(endDate) : ''; - const dateText = startDateText === endDateText - ? `${startDateText}` + return startDateText === endDateText + ? startDateText : `${startDateText} - ${endDateText}`; - - return `${dateText}`; } } From b33737b1690691618379747bad5455a4ed95ab9d Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Tue, 13 Jan 2026 14:01:41 +0100 Subject: [PATCH 2/8] test: add test --- .../timezone/appointmentCollectorTimezone.ts | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 e2e/testcafe-devextreme/tests/scheduler/common/timezone/appointmentCollectorTimezone.ts diff --git a/e2e/testcafe-devextreme/tests/scheduler/common/timezone/appointmentCollectorTimezone.ts b/e2e/testcafe-devextreme/tests/scheduler/common/timezone/appointmentCollectorTimezone.ts new file mode 100644 index 000000000000..c0e62a32062b --- /dev/null +++ b/e2e/testcafe-devextreme/tests/scheduler/common/timezone/appointmentCollectorTimezone.ts @@ -0,0 +1,57 @@ +import Scheduler from 'devextreme-testcafe-models/scheduler'; +import { createWidget } from '../../../../helpers/createWidget'; +import { getTimezoneTest, MACHINE_TIMEZONES } from '../../../../helpers/machineTimezones'; +import url from '../../../../helpers/getPageUrl'; + +fixture.disablePageReloads`Scheduler - Appointment Collector Timezone` + .page(url(__dirname, '../../../container.html')); + +[ + MACHINE_TIMEZONES.EuropeBerlin, +].forEach((machineTimezone) => { + getTimezoneTest([machineTimezone])( + 'Appointment collector button should have correct date', + async (t) => { + const scheduler = new Scheduler('#container'); + const schedulerCollector = scheduler.collectors.get(0); + const expectedDate = 'March 5, 2021'; + + const ariaRoleDescription = await schedulerCollector.element().getAttribute('aria-roledescription'); + + await t + .expect(scheduler.element().exists) + .ok() + .expect(ariaRoleDescription) + .contains(expectedDate, `Collector should display ${expectedDate} after timezone conversion`); + }, + ).before(async () => { + await createWidget('dxScheduler', { + timeZone: 'America/Los_Angeles', + dataSource: [ + { + text: 'Website Re-Design Plan', + startDate: new Date('2021-03-05T23:45:00.000Z'), + endDate: new Date('2021-03-05T18:15:00.000Z'), + }, + { + text: 'Complete Shipper Selection Form', + startDate: new Date('2021-03-05T15:30:00.000Z'), + endDate: new Date('2021-03-05T17:00:00.000Z'), + }, + { + text: 'Upgrade Server Hardware', + startDate: new Date('2021-03-05T19:00:00.000Z'), + endDate: new Date('2021-03-05T21:15:00.000Z'), + }, + { + text: 'Upgrade Personal Computers', + startDate: new Date('2021-03-05T21:45:00.000Z'), + endDate: new Date('2021-03-05T23:30:00.000Z'), + }, + ], + currentView: 'month', + currentDate: new Date(2021, 2, 1), + maxAppointmentsPerCell: 3, + }); + }); +}); From cc71dabbeed45c8697f1e64ca5978174ca1e0c1e Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Tue, 13 Jan 2026 14:01:51 +0100 Subject: [PATCH 3/8] Revert "test: fix bug" This reverts commit 3ca4956735b13372efbdd254a1f8e6bd5b660884. --- .../m_compact_appointments_helper.ts | 21 +++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/packages/devextreme/js/__internal/scheduler/m_compact_appointments_helper.ts b/packages/devextreme/js/__internal/scheduler/m_compact_appointments_helper.ts index 6adefc54f319..f7c4ab825c3e 100644 --- a/packages/devextreme/js/__internal/scheduler/m_compact_appointments_helper.ts +++ b/packages/devextreme/js/__internal/scheduler/m_compact_appointments_helper.ts @@ -127,10 +127,7 @@ export class CompactAppointmentsHelper { _createCompactButtonElement({ isCompact, $container, coordinates, sortedIndex, items, }: CompactAppointmentOptions) { - const appointmentDate = this._getDateText( - items[0].appointment, - items[0].targetedAppointment, - ); + const appointmentDate = this._getDateText(items[0].appointment); const result = $('
') .addClass(APPOINTMENT_COLLECTOR_CLASS) .attr('aria-roledescription', appointmentDate) @@ -190,18 +187,16 @@ export class CompactAppointmentsHelper { return date ? new Date(date) : null; } - _getDateText(appointment, targetedAppointment?) { - const displayStartDate = targetedAppointment?.displayStartDate; - const displayEndDate = targetedAppointment?.displayEndDate; - - const startDate = displayStartDate || this._getStartDate(appointment); - const endDate = displayEndDate || this._getEndDate(appointment); - + _getDateText(appointment) { + const startDate = this.instance._dataAccessors.get('startDate', appointment); + const endDate = this.instance._dataAccessors.get('endDate', appointment); const startDateText = startDate ? this._localizeDate(startDate) : ''; const endDateText = endDate ? this._localizeDate(endDate) : ''; - return startDateText === endDateText - ? startDateText + const dateText = startDateText === endDateText + ? `${startDateText}` : `${startDateText} - ${endDateText}`; + + return `${dateText}`; } } From 3dadaf686e8001cc334dfc898adb6fb6222f0848 Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Tue, 13 Jan 2026 14:16:35 +0100 Subject: [PATCH 4/8] test: move test to be executed --- .../appointmentCollectorTimezone.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) rename e2e/testcafe-devextreme/tests/scheduler/{common/timezone => timezones}/appointmentCollectorTimezone.ts (87%) diff --git a/e2e/testcafe-devextreme/tests/scheduler/common/timezone/appointmentCollectorTimezone.ts b/e2e/testcafe-devextreme/tests/scheduler/timezones/appointmentCollectorTimezone.ts similarity index 87% rename from e2e/testcafe-devextreme/tests/scheduler/common/timezone/appointmentCollectorTimezone.ts rename to e2e/testcafe-devextreme/tests/scheduler/timezones/appointmentCollectorTimezone.ts index c0e62a32062b..969525595836 100644 --- a/e2e/testcafe-devextreme/tests/scheduler/common/timezone/appointmentCollectorTimezone.ts +++ b/e2e/testcafe-devextreme/tests/scheduler/timezones/appointmentCollectorTimezone.ts @@ -1,10 +1,10 @@ import Scheduler from 'devextreme-testcafe-models/scheduler'; -import { createWidget } from '../../../../helpers/createWidget'; -import { getTimezoneTest, MACHINE_TIMEZONES } from '../../../../helpers/machineTimezones'; -import url from '../../../../helpers/getPageUrl'; +import { createWidget } from '../../../helpers/createWidget'; +import { getTimezoneTest, MACHINE_TIMEZONES } from '../../../helpers/machineTimezones'; +import url from '../../../helpers/getPageUrl'; fixture.disablePageReloads`Scheduler - Appointment Collector Timezone` - .page(url(__dirname, '../../../container.html')); + .page(url(__dirname, '../../container.html')); [ MACHINE_TIMEZONES.EuropeBerlin, From cc393f4856ec902d9376220b351a4bfdedfb9108 Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Tue, 13 Jan 2026 14:30:31 +0100 Subject: [PATCH 5/8] Revert "Revert "test: fix bug"" This reverts commit cc71dabbeed45c8697f1e64ca5978174ca1e0c1e. --- .../m_compact_appointments_helper.ts | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/packages/devextreme/js/__internal/scheduler/m_compact_appointments_helper.ts b/packages/devextreme/js/__internal/scheduler/m_compact_appointments_helper.ts index f7c4ab825c3e..6adefc54f319 100644 --- a/packages/devextreme/js/__internal/scheduler/m_compact_appointments_helper.ts +++ b/packages/devextreme/js/__internal/scheduler/m_compact_appointments_helper.ts @@ -127,7 +127,10 @@ export class CompactAppointmentsHelper { _createCompactButtonElement({ isCompact, $container, coordinates, sortedIndex, items, }: CompactAppointmentOptions) { - const appointmentDate = this._getDateText(items[0].appointment); + const appointmentDate = this._getDateText( + items[0].appointment, + items[0].targetedAppointment, + ); const result = $('
') .addClass(APPOINTMENT_COLLECTOR_CLASS) .attr('aria-roledescription', appointmentDate) @@ -187,16 +190,18 @@ export class CompactAppointmentsHelper { return date ? new Date(date) : null; } - _getDateText(appointment) { - const startDate = this.instance._dataAccessors.get('startDate', appointment); - const endDate = this.instance._dataAccessors.get('endDate', appointment); + _getDateText(appointment, targetedAppointment?) { + const displayStartDate = targetedAppointment?.displayStartDate; + const displayEndDate = targetedAppointment?.displayEndDate; + + const startDate = displayStartDate || this._getStartDate(appointment); + const endDate = displayEndDate || this._getEndDate(appointment); + const startDateText = startDate ? this._localizeDate(startDate) : ''; const endDateText = endDate ? this._localizeDate(endDate) : ''; - const dateText = startDateText === endDateText - ? `${startDateText}` + return startDateText === endDateText + ? startDateText : `${startDateText} - ${endDateText}`; - - return `${dateText}`; } } From 681ebd66a11f3391d41420bff1e1e1dd1957fbee Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Wed, 14 Jan 2026 16:35:22 +0100 Subject: [PATCH 6/8] fix: optimize solution --- .../m_compact_appointments_helper.ts | 29 +++++++------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/packages/devextreme/js/__internal/scheduler/m_compact_appointments_helper.ts b/packages/devextreme/js/__internal/scheduler/m_compact_appointments_helper.ts index 6adefc54f319..7901f248fbb8 100644 --- a/packages/devextreme/js/__internal/scheduler/m_compact_appointments_helper.ts +++ b/packages/devextreme/js/__internal/scheduler/m_compact_appointments_helper.ts @@ -6,6 +6,7 @@ import { FunctionTemplate } from '@js/core/templates/function_template'; import Button from '@js/ui/button'; import { APPOINTMENT_SETTINGS_KEY, LIST_ITEM_CLASS, LIST_ITEM_DATA_KEY } from './constants'; +import type Scheduler from './m_scheduler'; import type { AppointmentTooltipItem, CompactAppointmentOptions } from './types'; const APPOINTMENT_COLLECTOR_CLASS = 'dx-scheduler-appointment-collector'; @@ -15,7 +16,10 @@ const APPOINTMENT_COLLECTOR_CONTENT_CLASS = `${APPOINTMENT_COLLECTOR_CLASS}-cont export class CompactAppointmentsHelper { elements: any[] = []; - constructor(public instance) { + instance: Scheduler; + + constructor(instance: Scheduler) { + this.instance = instance; } render(options: CompactAppointmentOptions): dxElementWrapper { @@ -43,6 +47,7 @@ export class CompactAppointmentsHelper { const $button = $(e.element); this.instance.showAppointmentTooltipCore( $button, + // @ts-expect-error $button.data('items'), this._getExtraOptionsForTooltip(options, $button), ); @@ -96,6 +101,7 @@ export class CompactAppointmentsHelper { _createCompactButton(template, options: CompactAppointmentOptions) { const $button = this._createCompactButtonElement(options); + // @ts-expect-error return this.instance._createComponent($button, Button, { type: 'default', width: options.width, @@ -180,25 +186,12 @@ export class CompactAppointmentsHelper { return `${dateLocalization.format(date, 'monthAndDay')}, ${dateLocalization.format(date, 'year')}`; } - _getStartDate(appointment) { - const date = appointment.startDate; - return date ? new Date(date) : null; - } - - _getEndDate(appointment) { - const date = appointment.endDate; - return date ? new Date(date) : null; - } - _getDateText(appointment, targetedAppointment?) { - const displayStartDate = targetedAppointment?.displayStartDate; - const displayEndDate = targetedAppointment?.displayEndDate; - - const startDate = displayStartDate || this._getStartDate(appointment); - const endDate = displayEndDate || this._getEndDate(appointment); + const startDate = targetedAppointment?.displayStartDate || appointment.startDate; + const endDate = targetedAppointment?.displayEndDate || appointment.endDate; - const startDateText = startDate ? this._localizeDate(startDate) : ''; - const endDateText = endDate ? this._localizeDate(endDate) : ''; + const startDateText = this._localizeDate(startDate); + const endDateText = this._localizeDate(endDate); return startDateText === endDateText ? startDateText From e15656a6e34d370ec7f0ddd388b71f02632b8bf6 Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Thu, 15 Jan 2026 10:27:53 +0100 Subject: [PATCH 7/8] test: fix dates --- .../scheduler/timezones/appointmentCollectorTimezone.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/e2e/testcafe-devextreme/tests/scheduler/timezones/appointmentCollectorTimezone.ts b/e2e/testcafe-devextreme/tests/scheduler/timezones/appointmentCollectorTimezone.ts index 969525595836..f5799160193d 100644 --- a/e2e/testcafe-devextreme/tests/scheduler/timezones/appointmentCollectorTimezone.ts +++ b/e2e/testcafe-devextreme/tests/scheduler/timezones/appointmentCollectorTimezone.ts @@ -30,8 +30,8 @@ fixture.disablePageReloads`Scheduler - Appointment Collector Timezone` dataSource: [ { text: 'Website Re-Design Plan', - startDate: new Date('2021-03-05T23:45:00.000Z'), - endDate: new Date('2021-03-05T18:15:00.000Z'), + startDate: new Date('2021-03-05T15:30:00.000Z'), + endDate: new Date('2021-03-05T17:00:00.000Z'), }, { text: 'Complete Shipper Selection Form', @@ -45,8 +45,8 @@ fixture.disablePageReloads`Scheduler - Appointment Collector Timezone` }, { text: 'Upgrade Personal Computers', - startDate: new Date('2021-03-05T21:45:00.000Z'), - endDate: new Date('2021-03-05T23:30:00.000Z'), + startDate: new Date('2021-03-05T23:45:00.000Z'), + endDate: new Date('2021-03-06T01:30:00.000Z'), }, ], currentView: 'month', From c155ef91244b08ae7ef7292850ea37198a26ce68 Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Thu, 15 Jan 2026 10:47:09 +0100 Subject: [PATCH 8/8] refactor: add typing --- .../scheduler/m_compact_appointments_helper.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/devextreme/js/__internal/scheduler/m_compact_appointments_helper.ts b/packages/devextreme/js/__internal/scheduler/m_compact_appointments_helper.ts index 7901f248fbb8..ddacd7b40dd9 100644 --- a/packages/devextreme/js/__internal/scheduler/m_compact_appointments_helper.ts +++ b/packages/devextreme/js/__internal/scheduler/m_compact_appointments_helper.ts @@ -4,10 +4,11 @@ import messageLocalization from '@js/common/core/localization/message'; import $, { type dxElementWrapper } from '@js/core/renderer'; import { FunctionTemplate } from '@js/core/templates/function_template'; import Button from '@js/ui/button'; +import type { Appointment } from '@js/ui/scheduler'; import { APPOINTMENT_SETTINGS_KEY, LIST_ITEM_CLASS, LIST_ITEM_DATA_KEY } from './constants'; import type Scheduler from './m_scheduler'; -import type { AppointmentTooltipItem, CompactAppointmentOptions } from './types'; +import type { AppointmentTooltipItem, CompactAppointmentOptions, TargetedAppointment } from './types'; const APPOINTMENT_COLLECTOR_CLASS = 'dx-scheduler-appointment-collector'; const COMPACT_APPOINTMENT_COLLECTOR_CLASS = `${APPOINTMENT_COLLECTOR_CLASS}-compact`; @@ -186,9 +187,12 @@ export class CompactAppointmentsHelper { return `${dateLocalization.format(date, 'monthAndDay')}, ${dateLocalization.format(date, 'year')}`; } - _getDateText(appointment, targetedAppointment?) { - const startDate = targetedAppointment?.displayStartDate || appointment.startDate; - const endDate = targetedAppointment?.displayEndDate || appointment.endDate; + _getDateText( + appointment: Appointment, + targetedAppointment: Appointment | TargetedAppointment | undefined, + ): string { + const startDate = targetedAppointment?.displayStartDate ?? appointment.startDate; + const endDate = targetedAppointment?.displayEndDate ?? appointment.endDate; const startDateText = this._localizeDate(startDate); const endDateText = this._localizeDate(endDate);