From 204be55d99c1d9a06a038da9cb17dcf895e92ad6 Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Fri, 16 Jan 2026 12:23:27 +0100 Subject: [PATCH 1/2] fix: fix bug --- .../timezones/appointmentCollectorTimezone.ts | 57 +++++++++++++++++++ .../m_compact_appointments_helper.ts | 44 +++++++------- 2 files changed, 80 insertions(+), 21 deletions(-) create mode 100644 e2e/testcafe-devextreme/tests/scheduler/timezones/appointmentCollectorTimezone.ts diff --git a/e2e/testcafe-devextreme/tests/scheduler/timezones/appointmentCollectorTimezone.ts b/e2e/testcafe-devextreme/tests/scheduler/timezones/appointmentCollectorTimezone.ts new file mode 100644 index 000000000000..f5799160193d --- /dev/null +++ b/e2e/testcafe-devextreme/tests/scheduler/timezones/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-05T15:30:00.000Z'), + endDate: new Date('2021-03-05T17:00: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-05T23:45:00.000Z'), + endDate: new Date('2021-03-06T01:30:00.000Z'), + }, + ], + currentView: 'month', + currentDate: new Date(2021, 2, 1), + maxAppointmentsPerCell: 3, + }); + }); +}); 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 19e7db48c384..e13db784c4cf 100644 --- a/packages/devextreme/js/__internal/scheduler/m_compact_appointments_helper.ts +++ b/packages/devextreme/js/__internal/scheduler/m_compact_appointments_helper.ts @@ -4,9 +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 { AppointmentTooltipItem, CompactAppointmentOptions } from './types'; +import type Scheduler from './m_scheduler'; +import type { AppointmentTooltipItem, CompactAppointmentOptions, TargetedAppointment } from './types'; const APPOINTMENT_COLLECTOR_CLASS = 'dx-scheduler-appointment-collector'; const COMPACT_APPOINTMENT_COLLECTOR_CLASS = `${APPOINTMENT_COLLECTOR_CLASS}-compact`; @@ -15,7 +17,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 +48,7 @@ export class CompactAppointmentsHelper { const $button = $(e.element); this.instance.showAppointmentTooltipCore( $button, + // @ts-expect-error $button.data('items'), this._getExtraOptionsForTooltip(options, $button), ); @@ -97,6 +103,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, @@ -109,7 +116,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) @@ -159,26 +169,18 @@ 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: Appointment, + targetedAppointment: Appointment | TargetedAppointment | undefined, + ): string { + const startDate = targetedAppointment?.displayStartDate ?? appointment.startDate; + const endDate = targetedAppointment?.displayEndDate ?? appointment.endDate; - _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) : ''; + const startDateText = this._localizeDate(startDate); + const endDateText = this._localizeDate(endDate); - const dateText = startDateText === endDateText - ? `${startDateText}` + return startDateText === endDateText + ? startDateText : `${startDateText} - ${endDateText}`; - - return `${dateText}`; } } From 5907d30f91731616a7d43c51dbbef2fac2be98bf Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Fri, 16 Jan 2026 13:09:52 +0100 Subject: [PATCH 2/2] test: fix date in test --- .../tests/accessibility/scheduler/appointment.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/testcafe-devextreme/tests/accessibility/scheduler/appointment.ts b/e2e/testcafe-devextreme/tests/accessibility/scheduler/appointment.ts index 0448bd27a40b..b30219a4bc03 100644 --- a/e2e/testcafe-devextreme/tests/accessibility/scheduler/appointment.ts +++ b/e2e/testcafe-devextreme/tests/accessibility/scheduler/appointment.ts @@ -431,7 +431,7 @@ test('Scheduler a11y: appointments does not have info about reccurence', async ( test('Scheduler a11y: Appointment collector button doesn\'t have info about date', async (t) => { const scheduler = new Scheduler('#container'); const schedulerCollector = scheduler.collectors.get(0); - const dateText = 'March 6, 2021'; + const dateText = 'March 5, 2021'; await t .expect(scheduler.element().exists)