Scheduler - Virtual Scrolling - Support keyboard navigation #32743
Scheduler - Virtual Scrolling - Support keyboard navigation #32743Tucchhaa wants to merge 18 commits intoDevExpress:26_1from
Conversation
Signed-off-by: Eldar Iusupzhanov <84278206+Tucchhaa@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR updates the Scheduler’s appointment ordering pipeline to expose a “sorted appointments” list to the appointments collection, enabling deterministic keyboard navigation (Tab/Home/End) in virtual scrolling scenarios, and adds/updates automated tests around this behavior.
Changes:
- Introduces a dedicated sorting stage (
sortAppointments) that producesSortedEntity[]and is reused for view model generation and keyboard navigation. - Refactors workspace → scheduler integration from
onRenderAppointments/updateAppointmentstorenderAppointments. - Adds/updates QUnit + TestCafe coverage for keyboard navigation, including new E2E scenarios for virtual scrolling.
Reviewed changes
Copilot reviewed 15 out of 16 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/testcafe-models/scheduler/appointment/index.ts | Renames ctor filter param (title → text) used to locate appointments by text. |
| packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/appointments.tests.js | Aligns tests with “real scheduler” items flow and adds getSortedAppointments plumbing. |
| packages/devextreme/js/__internal/scheduler/workspaces/m_work_space.ts | Renames callback to renderAppointments and updates invocation site. |
| packages/devextreme/js/__internal/scheduler/workspaces/m_virtual_scrolling.ts | Uses workspace.renderAppointments() when virtual scrolling triggers re-render. |
| packages/devextreme/js/__internal/scheduler/view_model/types.ts | Introduces SortedEntity type and refactors AppointmentEntity composition. |
| packages/devextreme/js/__internal/scheduler/view_model/generate_view_model/generate_grid_view_model.ts | Splits sorting into sortAppointments() and updates grid VM generation to accept sorted input. |
| packages/devextreme/js/__internal/scheduler/view_model/appointments_layout_manager.ts | Stores and exposes sorted items for reuse (sortedItems). |
| packages/devextreme/js/__internal/scheduler/m_scheduler.ts | Wires getSortedAppointments + scrollTo into appointments config; renames workspace render hook. |
| packages/devextreme/js/__internal/scheduler/appointments/utils/sorted_index_utils.ts | Removes old DOM-based next/prev focus helpers. |
| packages/devextreme/js/__internal/scheduler/appointments/utils/sorted_index_utils.test.ts | Removes Jest coverage for the deleted helpers. |
| packages/devextreme/js/__internal/scheduler/appointments/m_appointments_kbn.ts | Reworks keyboard navigation to use sorted items and support virtual scrolling. |
| packages/devextreme/js/__internal/scheduler/appointments/m_appointment_collection.ts | Tracks elements by sorted index and preserves focus across re-render during virtual navigation. |
| e2e/testcafe-devextreme/tests/scheduler/helpers/generateAppointmentsWithResources.ts | Adds helper to generate large grouped datasets for E2E navigation tests. |
| e2e/testcafe-devextreme/tests/scheduler/common/keyboardNavigation/documentScrollPrevented.ts | Adds E2E checks for preventing document scroll on Home/End. |
| e2e/testcafe-devextreme/tests/scheduler/common/keyboardNavigation/appointments.ts | Expands E2E coverage for appointment keyboard navigation across scrolling modes. |
You can also share your feedback on Copilot code review. Take the survey.
e2e/testcafe-devextreme/tests/scheduler/common/keyboardNavigation/appointments.ts
Outdated
Show resolved
Hide resolved
packages/devextreme/js/__internal/scheduler/appointments/m_appointment_collection.ts
Show resolved
Hide resolved
packages/devextreme/js/__internal/scheduler/appointments/m_appointment_collection.ts
Show resolved
Hide resolved
packages/devextreme/js/__internal/scheduler/appointments/m_appointments_kbn.ts
Outdated
Show resolved
Hide resolved
packages/devextreme/js/__internal/scheduler/appointments/m_appointments_kbn.ts
Show resolved
Hide resolved
e2e/testcafe-devextreme/tests/scheduler/common/keyboardNavigation/appointments.ts
Outdated
Show resolved
Hide resolved
e2e/testcafe-devextreme/tests/scheduler/common/keyboardNavigation/appointments.ts
Outdated
Show resolved
Hide resolved
e2e/testcafe-devextreme/tests/scheduler/common/keyboardNavigation/appointments.ts
Outdated
Show resolved
Hide resolved
|
|
||
| public get sortedItems(): SortedEntity[] { return this._sortedItems; } | ||
|
|
||
| viewModel: AppointmentViewModelPlain[] = []; |
There was a problem hiding this comment.
Remove this, it's dead code
| // NOTE: fallback for integration testing | ||
| if (!this.renderedElementsBySortedIndex) { | ||
| this.renderedElementsBySortedIndex = []; | ||
| if (!this.$itemBySortedIndex) { |
There was a problem hiding this comment.
We can remove this line. You are add default value before
$itemBySortedIndex: dxElementWrapper[] = [];
| schedulerStore: Scheduler, | ||
| items: SortedEntity[], | ||
| ): AppointmentEntity[] => { | ||
| const optionManager = new OptionManager(schedulerStore); |
There was a problem hiding this comment.
Two OptionManager instances are created per render cycle — one here, one in generateGridViewModel above.
The constructor itself is cheap (plain .option() reads in getViewModelOptions).
The DOM access happens inside getPanelOptions(), which calls:
- workspace.getPanelDOMSize() — reads panel offsetWidth/offsetHeight
- workspace.getCollectorDimension() — reads collector CSS computed size
- workspace.getDOMElementsMetaData() — reads cell dimensions from DOM
These are guarded by cache.memo(), but each instance has its own Cache,DOM is re-read twice per render cycle.
If passing single shared instance into both functions would get rid duplication.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 15 out of 16 changed files in this pull request and generated 3 comments.
You can also share your feedback on Copilot code review. Take the survey.
No description provided.