From 933aea5c97446c0036f7869f29fc90b90f68ec13 Mon Sep 17 00:00:00 2001 From: Aleksey Semikozov Date: Thu, 23 Apr 2026 19:43:25 +0000 Subject: [PATCH 1/3] Scheduler - Move shaders into workspace, replace private access with public API --- .../scheduler/workspaces/m_timeline.ts | 2 +- .../scheduler/workspaces/m_work_space.ts | 26 +++++++++++++++- ..._work_space_grouped_strategy_horizontal.ts | 30 +++++++++---------- .../m_work_space_grouped_strategy_vertical.ts | 8 ++--- .../shaders/current_time_shader.ts | 4 +-- .../shaders/current_time_shader_horizontal.ts | 10 +++---- .../shaders/current_time_shader_vertical.ts | 8 ++--- 7 files changed, 56 insertions(+), 32 deletions(-) rename packages/devextreme/js/__internal/scheduler/{ => workspaces}/shaders/current_time_shader.ts (86%) rename packages/devextreme/js/__internal/scheduler/{ => workspaces}/shaders/current_time_shader_horizontal.ts (87%) rename packages/devextreme/js/__internal/scheduler/{ => workspaces}/shaders/current_time_shader_vertical.ts (94%) diff --git a/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline.ts b/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline.ts index 3be00b53ca44..6c043cdb78da 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline.ts @@ -17,8 +17,8 @@ import { } from '../m_classes'; import tableCreatorModule from '../m_table_creator'; import timezoneUtils from '../m_utils_time_zone'; -import HorizontalShader from '../shaders/current_time_shader_horizontal'; import SchedulerWorkSpace from './m_work_space_indicator'; +import HorizontalShader from './shaders/current_time_shader_horizontal'; const { tableCreator } = tableCreatorModule; diff --git a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space.ts b/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space.ts index 537381ca65a4..f0e3ea86a53b 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space.ts @@ -70,7 +70,6 @@ import { import type { SubscribeKey, SubscribeMethods } from '../m_subscribes'; import tableCreatorModule from '../m_table_creator'; import { utils } from '../m_utils'; -import VerticalShader from '../shaders/current_time_shader_vertical'; import type { ResourceLoader } from '../utils/loader/resource_loader'; import { getAppointmentGroupIndex, @@ -91,6 +90,7 @@ import CellsSelectionState from './m_cells_selection_state'; import { VirtualScrollingDispatcher, VirtualScrollingRenderer } from './m_virtual_scrolling'; import HorizontalGroupedStrategy from './m_work_space_grouped_strategy_horizontal'; import VerticalGroupedStrategy from './m_work_space_grouped_strategy_vertical'; +import VerticalShader from './shaders/current_time_shader_vertical'; import type { ViewDataProviderOptions } from './view_model/m_types'; import ViewDataProvider from './view_model/m_view_data_provider'; @@ -2896,6 +2896,30 @@ class SchedulerWorkSpace extends Widget { return this.$allDayContainer; } + getShaderContainer() { + return this._dateTableScrollable.$content(); + } + + getAllDayPanelElement() { + return this._$allDayPanel; + } + + getGroupCount() { + return this._getGroupCount(); + } + + getCellCount() { + return this._getCellCount(); + } + + isHorizontalGrouping() { + return this._isHorizontalGroupedWorkSpace(); + } + + getHeaderPanelContainer() { + return this._$headerPanelContainer; + } + updateRender() { this.renderer.updateRender(); } diff --git a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_grouped_strategy_horizontal.ts b/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_grouped_strategy_horizontal.ts index 5e728dfb8bdc..cd43197bfe43 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_grouped_strategy_horizontal.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_grouped_strategy_horizontal.ts @@ -15,27 +15,27 @@ class HorizontalGroupedStrategy { if (!groupByDay) { return { rowIndex: cellCoordinates.rowIndex, - columnIndex: cellCoordinates.columnIndex + groupIndex * this._workSpace._getCellCount(), + columnIndex: cellCoordinates.columnIndex + groupIndex * this._workSpace.getCellCount(), }; } return { rowIndex: cellCoordinates.rowIndex, - columnIndex: cellCoordinates.columnIndex * this._workSpace._getGroupCount() + groupIndex, + columnIndex: cellCoordinates.columnIndex * this._workSpace.getGroupCount() + groupIndex, }; } getGroupIndex(rowIndex, columnIndex) { const groupByDay = this._workSpace.isGroupedByDate(); - const groupCount = this._workSpace._getGroupCount(); + const groupCount = this._workSpace.getGroupCount(); if (groupByDay) { return columnIndex % groupCount; } - return Math.floor(columnIndex / this._workSpace._getCellCount()); + return Math.floor(columnIndex / this._workSpace.getCellCount()); } calculateHeaderCellRepeatCount() { - return this._workSpace._getGroupCount() || 1; + return this._workSpace.getGroupCount() || 1; } insertAllDayRowsIntoDateTable() { @@ -45,7 +45,7 @@ class HorizontalGroupedStrategy { getTotalCellCount(groupCount) { groupCount = groupCount || 1; - return this._workSpace._getCellCount() * groupCount; + return this._workSpace.getCellCount() * groupCount; } getTotalRowCount() { @@ -143,18 +143,18 @@ class HorizontalGroupedStrategy { private calculateOffset(groupIndex) { const indicatorStartPosition = this._workSpace.getIndicatorOffset(groupIndex); - const offset = this._workSpace._getCellCount() * this._workSpace.getCellWidth() * groupIndex; + const offset = this._workSpace.getCellCount() * this._workSpace.getRoundedCellWidth(groupIndex - 1, 0) * groupIndex; return indicatorStartPosition + offset; } private calculateGroupByDateOffset(groupIndex) { - return this._workSpace.getIndicatorOffset(0) * this._workSpace._getGroupCount() + this._workSpace.getCellWidth() * groupIndex; + return this._workSpace.getIndicatorOffset(0) * this._workSpace.getGroupCount() + this._workSpace.getRoundedCellWidth(groupIndex - 1, 0) * groupIndex; } getShaderOffset(i, width) { - const offset = this._workSpace._getCellCount() * this._workSpace.getCellWidth() * i; - return this._workSpace.option('rtlEnabled') ? getBoundingRect(this._workSpace._dateTableScrollable.$content().get(0)).width - offset - this._workSpace.getTimePanelWidth() - width : offset; + const offset = this._workSpace.getCellCount() * this._workSpace.getRoundedCellWidth(i - 1) * i; + return this._workSpace.option('rtlEnabled') ? getBoundingRect(this._workSpace.getShaderContainer().get(0)).width - offset - this._workSpace.getTimePanelWidth() - width : offset; } getShaderTopOffset(i) { @@ -168,7 +168,7 @@ class HorizontalGroupedStrategy { } getShaderMaxHeight() { - return getBoundingRect(this._workSpace._dateTableScrollable.$content().get(0)).height; + return getBoundingRect(this._workSpace.getShaderContainer().get(0)).height; } getShaderWidth() { @@ -197,10 +197,10 @@ class HorizontalGroupedStrategy { const groupByDate = this._workSpace.isGroupedByDate(); if (groupByDate) { - if (index % this._workSpace._getGroupCount() === 0) { + if (index % this._workSpace.getGroupCount() === 0) { return `${cellClass} ${LAST_GROUP_CELL_CLASS}`; } - } else if (index % this._workSpace._getCellCount() === 0) { + } else if (index % this._workSpace.getCellCount() === 0) { return `${cellClass} ${LAST_GROUP_CELL_CLASS}`; } @@ -215,10 +215,10 @@ class HorizontalGroupedStrategy { const groupByDate = this._workSpace.isGroupedByDate(); if (groupByDate) { - if ((index - 1) % this._workSpace._getGroupCount() === 0) { + if ((index - 1) % this._workSpace.getGroupCount() === 0) { return `${cellClass} ${FIRST_GROUP_CELL_CLASS}`; } - } else if ((index - 1) % this._workSpace._getCellCount() === 0) { + } else if ((index - 1) % this._workSpace.getCellCount() === 0) { return `${cellClass} ${FIRST_GROUP_CELL_CLASS}`; } diff --git a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_grouped_strategy_vertical.ts b/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_grouped_strategy_vertical.ts index ebbeb0e0f5d8..e57188e0b36d 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_grouped_strategy_vertical.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_grouped_strategy_vertical.ts @@ -46,15 +46,15 @@ class VerticalGroupedStrategy { } getTotalCellCount() { - return this._workSpace._getCellCount(); + return this._workSpace.getCellCount(); } getTotalRowCount() { - return this._workSpace.getRowCount() * this._workSpace._getGroupCount(); + return this._workSpace.getRowCount() * this._workSpace.getGroupCount(); } calculateTimeCellRepeatCount() { - return this._workSpace._getGroupCount() || 1; + return this._workSpace.getGroupCount() || 1; } getWorkSpaceMinWidth() { @@ -92,7 +92,7 @@ class VerticalGroupedStrategy { const dayHeight = (calculateDayDuration(startDayHour, endDayHour) / hoursInterval) * this._workSpace.getCellHeight(); const scrollTop = this.getScrollableScrollTop(); - const headerRowHeight = getBoundingRect(this._workSpace._$headerPanelContainer.get(0)).height; + const headerRowHeight = getBoundingRect(this._workSpace.getHeaderPanelContainer().get(0)).height; let topOffset = groupIndex * dayHeight + headerRowHeight + this._workSpace.option('getHeaderHeight')() - scrollTop; diff --git a/packages/devextreme/js/__internal/scheduler/shaders/current_time_shader.ts b/packages/devextreme/js/__internal/scheduler/workspaces/shaders/current_time_shader.ts similarity index 86% rename from packages/devextreme/js/__internal/scheduler/shaders/current_time_shader.ts rename to packages/devextreme/js/__internal/scheduler/workspaces/shaders/current_time_shader.ts index a68320810801..f8c3c9024048 100644 --- a/packages/devextreme/js/__internal/scheduler/shaders/current_time_shader.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/shaders/current_time_shader.ts @@ -1,12 +1,12 @@ import type { dxElementWrapper } from '@js/core/renderer'; import $ from '@js/core/renderer'; -import type SchedulerWorkSpace from '../workspaces/m_work_space'; +import type SchedulerWorkSpace from '../m_work_space'; const DATE_TIME_SHADER_CLASS = 'dx-scheduler-date-time-shader'; class CurrentTimeShader { - protected $container = this._workSpace._dateTableScrollable.$content(); + protected $container = this._workSpace.getShaderContainer(); _shader!: dxElementWrapper[]; diff --git a/packages/devextreme/js/__internal/scheduler/shaders/current_time_shader_horizontal.ts b/packages/devextreme/js/__internal/scheduler/workspaces/shaders/current_time_shader_horizontal.ts similarity index 87% rename from packages/devextreme/js/__internal/scheduler/shaders/current_time_shader_horizontal.ts rename to packages/devextreme/js/__internal/scheduler/workspaces/shaders/current_time_shader_horizontal.ts index 222888a95262..587d96beea82 100644 --- a/packages/devextreme/js/__internal/scheduler/shaders/current_time_shader_horizontal.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/shaders/current_time_shader_horizontal.ts @@ -6,8 +6,8 @@ import CurrentTimeShader from './current_time_shader'; class HorizontalCurrentTimeShader extends CurrentTimeShader { renderShader(): void { - const groupCount = this._workSpace._isHorizontalGroupedWorkSpace() - ? this._workSpace._getGroupCount() + const groupCount = this._workSpace.isHorizontalGrouping() + ? this._workSpace.getGroupCount() : 1; for (let i = 0; i < groupCount; i += 1) { @@ -34,7 +34,7 @@ class HorizontalCurrentTimeShader extends CurrentTimeShader { if (groupIndex >= 1) { const workSpace = this._workSpace; - const indicationWidth = workSpace._getCellCount() * workSpace.getCellWidth(); + const indicationWidth = workSpace.getCellCount() * workSpace.getCellWidth(); $shader.css('left', indicationWidth); } else { $shader.css('left', 0); @@ -64,9 +64,9 @@ class HorizontalCurrentTimeShader extends CurrentTimeShader { this.applyShaderWidth($shader, shaderWidth); if (isFirstShaderPart) { - shaderLeft = workSpace._getCellCount() * workSpace.getCellWidth() * groupIndex; + shaderLeft = workSpace.getCellCount() * workSpace.getCellWidth() * groupIndex; } else { - shaderLeft = workSpace.getCellWidth() * integerPart * workSpace._getGroupCount() + shaderLeft = workSpace.getCellWidth() * integerPart * workSpace.getGroupCount() + groupIndex * workSpace.getCellWidth(); } diff --git a/packages/devextreme/js/__internal/scheduler/shaders/current_time_shader_vertical.ts b/packages/devextreme/js/__internal/scheduler/workspaces/shaders/current_time_shader_vertical.ts similarity index 94% rename from packages/devextreme/js/__internal/scheduler/shaders/current_time_shader_vertical.ts rename to packages/devextreme/js/__internal/scheduler/workspaces/shaders/current_time_shader_vertical.ts index 09177d7dd36b..4f96d0bf02dd 100644 --- a/packages/devextreme/js/__internal/scheduler/shaders/current_time_shader_vertical.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/shaders/current_time_shader_vertical.ts @@ -24,7 +24,7 @@ class VerticalCurrentTimeShader extends CurrentTimeShader { } setHeight(this.$shader, shaderHeight); - const groupCount = this._workSpace._getGroupCount() || 1; + const groupCount = this._workSpace.getGroupCount() || 1; if (this._workSpace.isGroupedByDate()) { this.renderGroupedByDateShaderParts(groupCount, shaderHeight, maxHeight, isSolidShader); @@ -125,7 +125,7 @@ class VerticalCurrentTimeShader extends CurrentTimeShader { setWidth(this.$allDayIndicator, shaderWidth); this.$allDayIndicator.css('left', this.getShaderOffset(i, shaderWidth)); - this._workSpace._$allDayPanel.prepend(this.$allDayIndicator); + this._workSpace.getAllDayPanelElement().prepend(this.$allDayIndicator); } } @@ -152,8 +152,8 @@ class VerticalCurrentTimeShader extends CurrentTimeShader { clean(): void { super.clean(); - if (this._workSpace?._$allDayPanel) { - this._workSpace._$allDayPanel.find(`.${DATE_TIME_SHADER_ALL_DAY_CLASS}`).remove(); + if (this._workSpace?.getAllDayPanelElement()) { + this._workSpace.getAllDayPanelElement().find(`.${DATE_TIME_SHADER_ALL_DAY_CLASS}`).remove(); } } } From e6c29267f4d02b90d98805ea778c08ae952d45a5 Mon Sep 17 00:00:00 2001 From: Aleksey Semikozov Date: Thu, 23 Apr 2026 19:48:53 +0000 Subject: [PATCH 2/3] Scheduler - Replace private workspace access in subscribes, scheduler, and filter --- packages/devextreme/js/__internal/scheduler/m_subscribes.ts | 2 +- .../scheduler/view_model/filtering/create_appointment_filter.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/devextreme/js/__internal/scheduler/m_subscribes.ts b/packages/devextreme/js/__internal/scheduler/m_subscribes.ts index 26f8a025e16e..fb92515f8ecd 100644 --- a/packages/devextreme/js/__internal/scheduler/m_subscribes.ts +++ b/packages/devextreme/js/__internal/scheduler/m_subscribes.ts @@ -243,7 +243,7 @@ const subscribes = { }, getGroupCount() { - return this._workSpace._getGroupCount(); + return this._workSpace.getGroupCount(); }, mapAppointmentFields(config) { diff --git a/packages/devextreme/js/__internal/scheduler/view_model/filtering/create_appointment_filter.ts b/packages/devextreme/js/__internal/scheduler/view_model/filtering/create_appointment_filter.ts index 2f2b690e2564..21e085bd8bcb 100644 --- a/packages/devextreme/js/__internal/scheduler/view_model/filtering/create_appointment_filter.ts +++ b/packages/devextreme/js/__internal/scheduler/view_model/filtering/create_appointment_filter.ts @@ -31,7 +31,7 @@ export const createAppointmentFilter = (scheduler: Scheduler): FilterStrategy => viewType: (): ViewType => scheduler._workSpace.type as ViewType, viewDirection: (): 'vertical' | 'horizontal' => scheduler._workSpace.viewDirection as 'vertical' | 'horizontal', dateRange: (): Date[] => scheduler._workSpace.getDateRange() as Date[], - groupCount: (): number => scheduler._workSpace._getGroupCount() as number, + groupCount: (): number => scheduler._workSpace.getGroupCount() as number, viewDataProvider: (): ViewDataProvider => scheduler ._workSpace.viewDataProvider as ViewDataProvider, allDayPanelMode: (): AllDayPanelModeType => scheduler.getViewOption('allDayPanelMode'), From 25915716ea450d047a2e6996e466eff7a2cefe58 Mon Sep 17 00:00:00 2001 From: Aleksey Semikozov Date: Thu, 23 Apr 2026 19:53:47 +0000 Subject: [PATCH 3/3] Scheduler - Replace private workspace access in drag behavior and appointment filter --- .../scheduler/m_appointment_drag_behavior.ts | 2 +- .../filtering/create_appointment_filter.ts | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/devextreme/js/__internal/scheduler/m_appointment_drag_behavior.ts b/packages/devextreme/js/__internal/scheduler/m_appointment_drag_behavior.ts index f0e38b7dde97..b11af9497982 100644 --- a/packages/devextreme/js/__internal/scheduler/m_appointment_drag_behavior.ts +++ b/packages/devextreme/js/__internal/scheduler/m_appointment_drag_behavior.ts @@ -10,7 +10,7 @@ import type { AppointmentViewModelPlain } from './view_model/generate_view_model const APPOINTMENT_ITEM_CLASS = 'dx-scheduler-appointment'; export default class AppointmentDragBehavior { - workspace = this.scheduler._workSpace; + workspace = this.scheduler.getWorkSpace(); appointments = this.scheduler._appointments; diff --git a/packages/devextreme/js/__internal/scheduler/view_model/filtering/create_appointment_filter.ts b/packages/devextreme/js/__internal/scheduler/view_model/filtering/create_appointment_filter.ts index 21e085bd8bcb..3a422ac48754 100644 --- a/packages/devextreme/js/__internal/scheduler/view_model/filtering/create_appointment_filter.ts +++ b/packages/devextreme/js/__internal/scheduler/view_model/filtering/create_appointment_filter.ts @@ -27,13 +27,13 @@ export const createAppointmentFilter = (scheduler: Scheduler): FilterStrategy => showAllDayPanel: (): boolean => scheduler.option('showAllDayPanel'), timeZoneCalculator: scheduler.timeZoneCalculator, // - supportAllDayRow: scheduler._workSpace.supportAllDayRow(), - viewType: (): ViewType => scheduler._workSpace.type as ViewType, - viewDirection: (): 'vertical' | 'horizontal' => scheduler._workSpace.viewDirection as 'vertical' | 'horizontal', - dateRange: (): Date[] => scheduler._workSpace.getDateRange() as Date[], - groupCount: (): number => scheduler._workSpace.getGroupCount() as number, + supportAllDayRow: scheduler.getWorkSpace().supportAllDayRow(), + viewType: (): ViewType => scheduler.getWorkSpace().type as ViewType, + viewDirection: (): 'vertical' | 'horizontal' => scheduler.getWorkSpace().viewDirection as 'vertical' | 'horizontal', + dateRange: (): Date[] => scheduler.getWorkSpace().getDateRange() as Date[], + groupCount: (): number => scheduler.getWorkSpace().getGroupCount() as number, viewDataProvider: (): ViewDataProvider => scheduler - ._workSpace.viewDataProvider as ViewDataProvider, + .getWorkSpace().viewDataProvider as ViewDataProvider, allDayPanelMode: (): AllDayPanelModeType => scheduler.getViewOption('allDayPanelMode'), }; const filterStrategyName = scheduler.isVirtualScrolling()