From 7fe56dba0e1cf635dd318c252267ecf5ae0378a1 Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Tue, 2 Jun 2026 13:27:28 +0200 Subject: [PATCH 01/21] refactor: refactor ts --- .../scheduler/workspaces/m_agenda.ts | 304 ++++++++++-------- .../scheduler/workspaces/m_timeline.ts | 180 ++++++----- .../scheduler/workspaces/m_timeline_day.ts | 7 +- .../scheduler/workspaces/m_timeline_month.ts | 48 +-- .../scheduler/workspaces/m_timeline_week.ts | 7 +- .../scheduler/workspaces/m_work_space.ts | 121 +++++-- .../scheduler/workspaces/m_work_space_day.ts | 7 +- .../workspaces/m_work_space_indicator.ts | 101 +++--- .../workspaces/m_work_space_month.ts | 78 +++-- .../scheduler/workspaces/m_work_space_week.ts | 7 +- 10 files changed, 529 insertions(+), 331 deletions(-) diff --git a/packages/devextreme/js/__internal/scheduler/workspaces/m_agenda.ts b/packages/devextreme/js/__internal/scheduler/workspaces/m_agenda.ts index 75beb7059358..56d06698a036 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_agenda.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/m_agenda.ts @@ -2,12 +2,13 @@ import dateLocalization from '@js/common/core/localization/date'; import registerComponent from '@js/core/component_registrator'; import domAdapter from '@js/core/dom_adapter'; import { getPublicElement } from '@js/core/element'; -import $ from '@js/core/renderer'; +import $, { type dxElementWrapper } from '@js/core/renderer'; import { noop } from '@js/core/utils/common'; import dateUtils from '@js/core/utils/date'; import { extend } from '@js/core/utils/extend'; import { each } from '@js/core/utils/iterator'; import { setHeight, setOuterHeight } from '@js/core/utils/size'; +import type { OptionChanged } from '@ts/core/widget/types'; import { EMPTY_ACTIVE_STATE_UNIT } from '@ts/core/widget/widget'; import { @@ -23,7 +24,7 @@ import { VIEWS } from '../utils/options/constants_view'; import { reduceResourcesTree } from '../utils/resource_manager/agenda_group_utils'; import type { GroupNode } from '../utils/resource_manager/types'; import type { ListEntity } from '../view_model/types'; -import WorkSpace from './m_work_space'; +import WorkSpace, { type WorkspaceDateTableScrollableConfig, type WorkspaceOptionChangedOptions, type WorkspaceOptionsInternal } from './m_work_space'; const { tableCreator } = tableCreatorModule; @@ -40,40 +41,57 @@ const LAST_ROW_CLASS = 'dx-scheduler-date-table-last-row'; const INNER_CELL_MARGIN = 5; const OUTER_CELL_MARGIN = 20; +interface AgendaDefaultOptions extends WorkspaceOptionsInternal { + agendaDuration: number; + rowHeight: number; + noDataText: string; +} + +interface AgendaRenderOptions { + container: Element; + rowCount?: number; + cellCount?: number; + rowClass?: string; + cellClass?: string; + cellTemplate?: unknown; + getStartDate?: (rowIndex: number) => Date; +} + class SchedulerAgenda extends WorkSpace { - private startViewDate: any; + private startViewDate!: Date; private rows: number[][] = []; - private $rows: any; + private $rows: dxElementWrapper[] = []; - private $noDataContainer: any; + private $noDataContainer?: dxElementWrapper; - // eslint-disable-next-line class-methods-use-this protected _activeStateUnit(): string { return EMPTY_ACTIVE_STATE_UNIT; } - get type() { return VIEWS.AGENDA; } + get type(): string { return VIEWS.AGENDA; } - getStartViewDate() { + getStartViewDate(): Date { return this.startViewDate; } - _init() { + _init(): void { super._init(); } - _getDefaultOptions() { - return extend(super._getDefaultOptions(), { + _getDefaultOptions(): AgendaDefaultOptions { + const defaultOptions = extend(super._getDefaultOptions(), { // Number | "month" agendaDuration: 7, rowHeight: 60, noDataText: '', - }); + }) as AgendaDefaultOptions; + + return defaultOptions; } - _optionChanged(args) { + _optionChanged(args: OptionChanged): void { const { name } = args; const { value } = args; @@ -85,7 +103,7 @@ class SchedulerAgenda extends WorkSpace { this.recalculateAgenda(this.rows); break; case 'groups': - if (!value?.length) { + if (!Array.isArray(value) || !value.length) { if (this.$groupTable) { this.$groupTable.remove(); this.$groupTable = null; @@ -102,41 +120,41 @@ class SchedulerAgenda extends WorkSpace { } } - _renderFocusState() { return noop(); } + _renderFocusState(): void { return noop(); } - _renderFocusTarget() { return noop(); } + _renderFocusTarget(): void { return noop(); } - _cleanFocusState() { return noop(); } + _cleanFocusState(): void { return noop(); } - supportAllDayRow() { + supportAllDayRow(): boolean { return false; } - protected override isVerticalGroupedWorkSpace() { + protected override isVerticalGroupedWorkSpace(): boolean { return false; } - protected override getElementClass() { + protected override getElementClass(): string { return AGENDA_CLASS; } - protected override getRowCount() { + protected override getRowCount(): number { return this.option('agendaDuration') as number; } - getCellCount() { + getCellCount(): number { return 1; } - protected override getTimePanelRowCount() { + protected override getTimePanelRowCount(): number { return this.option('agendaDuration') as number; } - protected renderAllDayPanel() { return noop(); } + protected renderAllDayPanel(): void { return noop(); } - protected override updateAllDayVisibility() { return noop(); } + protected override updateAllDayVisibility(): void { return noop(); } - protected override initWorkSpaceUnits() { + protected override initWorkSpaceUnits(): void { this.initGroupTable(); this.$timePanel = $('').attr('aria-hidden', true).addClass(TIME_PANEL_CLASS); this.$dateTable = $('
').attr('aria-hidden', true).addClass(DATE_TABLE_CLASS); @@ -144,20 +162,20 @@ class SchedulerAgenda extends WorkSpace { this.$dateTableContainer = $('
').addClass('dx-scheduler-date-table-container'); } - private initGroupTable() { + private initGroupTable(): void { const groups = this.option('groups'); if (groups?.length) { this.$groupTable = $('
').attr('aria-hidden', true).addClass(GROUP_TABLE_CLASS); } } - protected override renderView() { + protected override renderView(): void { this.startViewDate = agendaUtils.calculateStartViewDate(this.option('currentDate') as any, this.option('startDayHour') as any); this.rows = []; } - private recalculateAgenda(rows) { - let cellTemplates = []; + private recalculateAgenda(rows: number[][]): void { + let cellTemplates: unknown[] = []; this.cleanView(); if (this.rowsIsEmpty(rows)) { @@ -177,21 +195,26 @@ class SchedulerAgenda extends WorkSpace { this.$dateTableScrollable.update(); } - private renderNoData() { + private renderNoData(): void { this.$noDataContainer = $('
').addClass(NODATA_CONTAINER_CLASS) - .html(this.option('noDataText') as any); + .html(this.option('noDataText') as string); this.$dateTableScrollable.$content().append(this.$noDataContainer); } - protected override setTableSizes() { return noop(); } + protected override setTableSizes(): void { return noop(); } - protected override toggleHorizontalScrollClass() { return noop(); } + protected override toggleHorizontalScrollClass(): void { return noop(); } - // eslint-disable-next-line @typescript-eslint/no-unused-vars - protected override createCrossScrollingConfig(argument?: any) { return noop(); } + protected override createCrossScrollingConfig(): Pick { + return { + direction: 'both', + onScroll: noop, + onEnd: noop, + }; + } - private setGroupHeaderCellsHeight() { + private setGroupHeaderCellsHeight(): void { const $cells = this.getGroupHeaderCells().filter((_, element) => !element.getAttribute('rowSpan')); const rows = this.removeEmptyRows(this.rows); @@ -199,72 +222,58 @@ class SchedulerAgenda extends WorkSpace { return; } - for (let i = 0; i < $cells.length; i++) { + for (let i = 0; i < $cells.length; i += 1) { const $cellContent = $cells.eq(i).find('.dx-scheduler-group-header-content'); setOuterHeight($cellContent, this.getGroupRowHeight(rows[i])); } } - private rowsIsEmpty(rows) { - let result = true; - - for (let i = 0; i < rows.length; i++) { - const groupRow = rows[i]; - - for (let j = 0; j < groupRow.length; j++) { - if (groupRow[j]) { - result = false; - break; - } - } - } - - return result; + private rowsIsEmpty(rows: number[][]): boolean { + return rows.every((groupRow) => groupRow.every((cell) => !cell)); } - protected override attachGroupCountClass() { + protected override attachGroupCountClass(): void { const className = getVerticalGroupCountClass(this.option('groups')); - (this.$element() as any).addClass(className); - } - - private removeEmptyRows(rows) { - const result: any[] = []; - const isEmpty = function (data) { - return !data.some((value) => value > 0); - }; - - for (let i = 0; i < rows.length; i++) { - if (rows[i].length && !isEmpty(rows[i])) { - result.push(rows[i]); - } + if (className) { + this.$element().addClass(className); } + } - return result; + private removeEmptyRows(rows: number[][]): number[][] { + const isEmpty = (data: number[]): boolean => !data.some((value) => value > 0); + return rows.filter((row) => row.length && !isEmpty(row)); } - protected override getGroupHeaderContainer() { - return this.$groupTable; + protected override getGroupHeaderContainer(): dxElementWrapper | null { + return this.$groupTable as dxElementWrapper | null; } - protected override makeGroupRows() { + protected override makeGroupRows(): { elements: dxElementWrapper; cellTemplates: unknown[] } { const resourceManager = this.option('getResourceManager')(); - const allAppointments = (this.option('getFilteredItems') as any)() as ListEntity[]; + const allAppointments = (this.option('getFilteredItems') as () => ListEntity[])(); const tree = reduceResourcesTree( resourceManager.resourceById, resourceManager.groupsTree, allAppointments, ); - const cellTemplate: any = this.option('resourceCellTemplate'); + const cellTemplate = this.option('resourceCellTemplate') as { + render?: (model: unknown) => unknown; + }; const getGroupHeaderContentClass = GROUP_HEADER_CONTENT_CLASS; - const cellTemplates: any[] = []; + const cellTemplates: unknown[] = []; const table = tableCreator.makeGroupedTableFromJSON(tree, { cellTag: 'th', groupTableClass: GROUP_TABLE_CLASS, groupRowClass: GROUP_ROW_CLASS, groupCellClass: this.getGroupHeaderClass(), - groupCellCustomContent(cell: HTMLDivElement, cellTextElement: HTMLElement, index: number, node: GroupNode) { + groupCellCustomContent( + cell: HTMLDivElement, + cellTextElement: HTMLElement, + index: number, + node: GroupNode, + ) { const container = domAdapter.createElement('div'); container.className = getGroupHeaderContentClass; const value = node.grouped[node.resourceIndex]; @@ -302,7 +311,7 @@ class SchedulerAgenda extends WorkSpace { }; } - protected override cleanView() { + protected override cleanView(): void { this.$dateTable.empty(); this.$timePanel.empty(); @@ -318,11 +327,11 @@ class SchedulerAgenda extends WorkSpace { } } - protected override createWorkSpaceElements() { + protected override createWorkSpaceElements(): void { this.createWorkSpaceStaticElements(); } - protected override createWorkSpaceStaticElements() { + protected override createWorkSpaceStaticElements(): void { this.$dateTableContainer.append(this.$dateTable); this.$dateTableScrollable.$content().append(this.$dateTableScrollableContent); @@ -334,7 +343,7 @@ class SchedulerAgenda extends WorkSpace { this.$element().append(this.$dateTableScrollable.$element()); } - protected renderDateTable() { + protected renderDateTable(): void { this.renderTableBody({ container: getPublicElement(this.$dateTable), rowClass: DATE_TABLE_ROW_CLASS, @@ -342,15 +351,29 @@ class SchedulerAgenda extends WorkSpace { }); } - protected override attachTablesEvents() { return noop(); } + protected override attachTablesEvents(): void { return noop(); } - protected override attachEvents() { return noop(); } + protected override attachEvents(): void { return noop(); } - isIndicationAvailable() { + isIndicationAvailable(): boolean { return false; } - private prepareCellTemplateOptions(text, date, rowIndex, $cell) { + private prepareCellTemplateOptions( + text: string, + date: Date | undefined, + rowIndex: number, + $cell: dxElementWrapper, + ): { + model: { + text: string; + date: Date | undefined; + groups: Record; + groupIndex: number | undefined; + }; + container: Element; + index: number; + } { const leaf = this.resourceManager.groupsLeafs[rowIndex]; const groups = leaf?.grouped ?? {}; const groupIndex = leaf?.groupIndex; @@ -367,31 +390,42 @@ class SchedulerAgenda extends WorkSpace { }; } - // eslint-disable-next-line @typescript-eslint/no-unused-vars - protected renderTableBody(options: any, delayCellTemplateRendering?: any) { - const cellTemplates: any[] = []; - const cellTemplateOpt = options.cellTemplate; + protected renderTableBody( + options: AgendaRenderOptions, + delayCellTemplateRendering?: unknown, + ): void { + if (delayCellTemplateRendering) { + noop(); + } + const cellTemplates: unknown[] = []; + const cellTemplateOpt = options.cellTemplate as { + render?: (templateOptions: unknown) => unknown; + } | undefined; this.$rows = []; - let i; + let i = 0; - const fillTableBody = function (rowIndex, rowSize) { + const fillTableBody = (rowIndex: number, rowSize: number): void => { if (rowSize) { - let date; - let cellDateNumber; - let cellDayName; + const date = options.getStartDate?.(rowIndex); + let cellDateNumber = ''; + let cellDayName = ''; const $row = $('
'); const $td = $('
'); setHeight($td, this.getRowHeight(rowSize)); - if (options.getStartDate) { - date = options.getStartDate?.(rowIndex); - cellDateNumber = dateLocalization.format(date, 'd'); - cellDayName = dateLocalization.format(date, formatWeekday); + if (date) { + cellDateNumber = String(dateLocalization.format(date, 'd')); + cellDayName = String(dateLocalization.format(date, formatWeekday)); } if (cellTemplateOpt?.render) { - const templateOptions = this.prepareCellTemplateOptions(`${cellDateNumber} ${cellDayName}`, date, i, $td); + const templateOptions = this.prepareCellTemplateOptions( + `${cellDateNumber} ${cellDayName}`, + date, + i, + $td, + ); cellTemplates.push(cellTemplateOpt.render.bind(cellTemplateOpt, templateOptions)); } else if (cellDateNumber && cellDayName) { @@ -409,10 +443,10 @@ class SchedulerAgenda extends WorkSpace { $row.append($td); this.$rows.push($row); } - }.bind(this); + }; - for (i = 0; i < this.rows.length; i++) { - each(this.rows[i], fillTableBody); + for (i = 0; i < this.rows.length; i += 1) { + each(this.rows[i], fillTableBody.bind(this)); this.setLastRowClass(); } @@ -420,7 +454,7 @@ class SchedulerAgenda extends WorkSpace { this.applyCellTemplates(cellTemplates); } - private setLastRowClass() { + private setLastRowClass(): void { if (this.rows.length > 1 && this.$rows.length) { const $lastRow = this.$rows[this.$rows.length - 1]; @@ -428,7 +462,7 @@ class SchedulerAgenda extends WorkSpace { } } - protected renderTimePanel() { + protected renderTimePanel(): void { this.renderTableBody({ container: getPublicElement(this.$timePanel), rowCount: this.getTimePanelRowCount(), @@ -440,32 +474,26 @@ class SchedulerAgenda extends WorkSpace { }); } - private getTimePanelStartDate(rowIndex) { + private getTimePanelStartDate(rowIndex: number): Date { const current = new Date(this.option('currentDate') as any); const cellDate = new Date(current.setDate(current.getDate() + rowIndex)); return cellDate; } - private getRowHeight(rowSize) { - const baseHeight = this.option('rowHeight') as any; + private getRowHeight(rowSize: number): number { + const baseHeight = this.option('rowHeight') as number; const innerOffset = (rowSize - 1) * INNER_CELL_MARGIN; return rowSize ? (baseHeight * rowSize) + innerOffset + OUTER_CELL_MARGIN : 0; } - private getGroupRowHeight(groupRows) { + private getGroupRowHeight(groupRows: number[] | undefined): number { if (!groupRows) { - return; - } - - let result = 0; - - for (let i = 0; i < groupRows.length; i++) { - result += this.getRowHeight(groupRows[i]); + return 0; } - return result; + return groupRows.reduce((result, groupRow) => result + this.getRowHeight(groupRow), 0); } renderAgendaLayout(appointments: ListEntity[]): void { @@ -480,39 +508,47 @@ class SchedulerAgenda extends WorkSpace { this.recalculateAgenda(rows); } - getAgendaVerticalStepHeight() { - return this.option('rowHeight'); + getAgendaVerticalStepHeight(): number { + return this.option('rowHeight') as number; } - getEndViewDate() { - const currentDate = new Date(this.option('currentDate') as any); - const agendaDuration: any = this.option('agendaDuration'); + getEndViewDate(): Date { + const currentDate = new Date(this.option('currentDate')); + const agendaDuration = this.option('agendaDuration') as number; - currentDate.setHours(this.option('endDayHour') as any); + currentDate.setHours(this.option('endDayHour')); const result = currentDate.setDate(currentDate.getDate() + agendaDuration - 1) - 60000; return new Date(result); } - getEndViewDateByEndDayHour() { + getEndViewDateByEndDayHour(): Date { return this.getEndViewDate(); } - updateScrollPosition(date) { + updateScrollPosition(date: Date): void { const newDate = this.timeZoneCalculator.createDate(date, 'toGrid'); const bounds = this.getVisibleBounds(); - const startDateHour = newDate.getHours(); - const startDateMinutes = newDate.getMinutes(); - if (this.needUpdateScrollPosition(startDateHour, startDateMinutes, bounds, newDate)) { + if (this.needUpdateScrollPosition(newDate, bounds)) { this.scrollTo(newDate); } } - // eslint-disable-next-line @typescript-eslint/no-unused-vars - needUpdateScrollPosition(hours, minutes, bounds, newData?: any) { + needUpdateScrollPosition( + date: Date, + appointmentGroupValues?: unknown, + inAllDayRow?: boolean, + ): boolean { + if (appointmentGroupValues || inAllDayRow) { + noop(); + } + + const bounds = this.getVisibleBounds(); + const hours = date.getHours(); + const minutes = date.getMinutes(); let isUpdateNeeded = false; if (hours < bounds.top.hours || hours > bounds.bottom.hours) { @@ -530,15 +566,18 @@ class SchedulerAgenda extends WorkSpace { return isUpdateNeeded; } - renovatedRenderSupported() { return false; } + renovatedRenderSupported(): boolean { return false; } - override isVirtualScrolling() { return false; } + override isVirtualScrolling(): boolean { return false; } - protected override getTotalViewDuration() { - return dateUtils.dateToMilliseconds('day') * (this.option('intervalCount') as any); + protected override getTotalViewDuration(): number { + return dateUtils.dateToMilliseconds('day') * this.option('intervalCount'); } - getDOMElementsMetaData() { + getDOMElementsMetaData(): { + dateTableCellsMeta: Record[][]; + allDayPanelCellsMeta: Record[]; + } { return { dateTableCellsMeta: [[{}]], allDayPanelCellsMeta: [{}], @@ -546,6 +585,7 @@ class SchedulerAgenda extends WorkSpace { } } +// eslint-disable-next-line @typescript-eslint/no-explicit-any registerComponent('dxSchedulerAgenda', SchedulerAgenda as any); export default SchedulerAgenda; diff --git a/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline.ts b/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline.ts index 9c7472ad4797..861a32b40a8b 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline.ts @@ -1,11 +1,12 @@ import registerComponent from '@js/core/component_registrator'; -import $ from '@js/core/renderer'; +import $, { type dxElementWrapper } from '@js/core/renderer'; import { noop } from '@js/core/utils/common'; import dateUtils from '@js/core/utils/date'; import { extend } from '@js/core/utils/extend'; import { getBoundingRect } from '@js/core/utils/position'; import { getOuterHeight, getOuterWidth, setHeight } from '@js/core/utils/size'; import { hasWindow } from '@js/core/utils/window'; +import type { dxSchedulerOptions } from '@js/ui/scheduler'; // NOTE: Renovation component import. import { HeaderPanelTimelineComponent } from '@ts/scheduler/r1/components/index'; import { timelineWeekUtils } from '@ts/scheduler/r1/utils/index'; @@ -17,7 +18,9 @@ import { 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 type { WorkspaceDateTableScrollableConfig, WorkspaceHeaderScrollableConfig } from './m_work_space'; +import SchedulerWorkSpace, { type WorkSpaceIndicatorDefaultOptions } from './m_work_space_indicator'; +import type { ViewDataProviderOptions } from './view_model/m_types'; const { tableCreator } = tableCreatorModule; @@ -32,76 +35,89 @@ const HEADER_PANEL_WEEK_CELL_CLASS = 'dx-scheduler-header-panel-week-cell'; const HORIZONTAL = 'horizontal'; const toMs = dateUtils.dateToMilliseconds; +interface TimelineDefaultOptions extends WorkSpaceIndicatorDefaultOptions { + groupOrientation: 'vertical'; +} + class SchedulerTimeline extends SchedulerWorkSpace { - protected override $sidebarTable: any; + protected override $sidebarTable!: dxElementWrapper; - get verticalGroupTableClass() { return GROUP_TABLE_CLASS; } + get verticalGroupTableClass(): string { return GROUP_TABLE_CLASS; } readonly viewDirection = 'horizontal'; - get renovatedHeaderPanelComponent() { return HeaderPanelTimelineComponent; } + get renovatedHeaderPanelComponent(): typeof HeaderPanelTimelineComponent { + return HeaderPanelTimelineComponent; + } - getGroupTableWidth() { - return this.$sidebarTable ? getOuterWidth(this.$sidebarTable) : 0; + getGroupTableWidth(): number { + return this.$sidebarTable ? getOuterWidth(this.$sidebarTable) as number : 0; } - protected override getTotalRowCount(groupCount) { + protected override getTotalRowCount( + groupCount: number, + includeAllDayPanelRows?: unknown, + ): number { + if (includeAllDayPanelRows !== undefined) { + noop(); + } + if (this.isHorizontalGroupedWorkSpace()) { return this.getRowCount(); } - groupCount = groupCount || 1; - return this.getRowCount() * groupCount; + const totalGroupCount = groupCount || 1; + return this.getRowCount() * totalGroupCount; } - protected override getFormat(): any { + protected override getFormat(): string { return 'shorttime'; } - private getWorkSpaceHeight() { + private getWorkSpaceHeight(): number { if (this.option('crossScrollingEnabled') && hasWindow()) { - return getBoundingRect(this.$dateTable.get(0)).height; + return getBoundingRect(this.$dateTable.get(0)).height as number; } - return getBoundingRect((this.$element() as any).get(0)).height; + return getBoundingRect(this.$element().get(0)).height as number; } - protected override dateTableScrollableConfig() { + protected override dateTableScrollableConfig(): WorkspaceDateTableScrollableConfig { const config = super.dateTableScrollableConfig(); const timelineConfig = { direction: HORIZONTAL, }; - return this.option('crossScrollingEnabled') ? config : extend(config, timelineConfig); + return this.option('crossScrollingEnabled') ? config : extend(config, timelineConfig) as WorkspaceDateTableScrollableConfig; } - protected override needCreateCrossScrolling() { + protected override needCreateCrossScrolling(): boolean { return true; } - protected override headerScrollableConfig() { + protected override headerScrollableConfig(): WorkspaceHeaderScrollableConfig { const config = super.headerScrollableConfig(); return extend(config, { scrollByContent: true, - }); + }) as WorkspaceHeaderScrollableConfig; } - supportAllDayRow() { + supportAllDayRow(): boolean { return false; } - protected override getGroupHeaderContainer() { + protected override getGroupHeaderContainer(): dxElementWrapper { if (this.isHorizontalGroupedWorkSpace()) { - return this.$thead; + return this.$thead as dxElementWrapper; } return this.$sidebarTable; } - protected override insertAllDayRowsIntoDateTable() { + protected override insertAllDayRowsIntoDateTable(): boolean { return false; } - protected needRenderWeekHeader() { + protected needRenderWeekHeader(): boolean { return false; } @@ -109,12 +125,12 @@ class SchedulerTimeline extends SchedulerWorkSpace { date.setDate(date.getDate() + 1); } - getIndicationCellCount() { + getIndicationCellCount(): number { const timeDiff = this.getTimeDiff(); return this.calculateDurationInCells(timeDiff); } - private getTimeDiff() { + private getTimeDiff(): number { let today = this.getToday(); const date = this.getIndicationFirstViewDate(); @@ -128,12 +144,12 @@ class SchedulerTimeline extends SchedulerWorkSpace { return today.getTime() - date.getTime(); } - protected calculateDurationInCells(timeDiff) { + protected calculateDurationInCells(timeDiff: number): number { const today = this.getToday(); const differenceInDays = Math.floor(timeDiff / toMs('day')); - let duration = (timeDiff - differenceInDays * toMs('day') - (this.option('startDayHour') as any) * toMs('hour')) / this.getCellDuration(); + let duration = (timeDiff - differenceInDays * toMs('day') - this.option('startDayHour') * toMs('hour')) / this.getCellDuration(); - if (today.getHours() > (this.option('endDayHour') as any)) { + if (today.getHours() > this.option('endDayHour')) { duration = this.getCellCountInDay(); } @@ -143,7 +159,7 @@ class SchedulerTimeline extends SchedulerWorkSpace { return differenceInDays * this.getCellCountInDay() + duration; } - getIndicationWidth() { + getIndicationWidth(): number { if (this.isGroupedByDate()) { const cellCount = this.getIndicationCellCount(); const integerPart = Math.floor(cellCount); @@ -154,15 +170,15 @@ class SchedulerTimeline extends SchedulerWorkSpace { return this.getIndicationCellCount() * this.getCellWidth(); } - protected override isVerticalShader() { + protected override isVerticalShader(): boolean { return false; } - protected override isCurrentTimeHeaderCell() { + protected override isCurrentTimeHeaderCell(): boolean { return false; } - protected override setTableSizes() { + protected override setTableSizes(): void { super.setTableSizes(); const minHeight = this.getWorkSpaceMinHeight(); @@ -172,7 +188,7 @@ class SchedulerTimeline extends SchedulerWorkSpace { this.virtualScrollingDispatcher.updateDimensions(); } - private getWorkSpaceMinHeight() { + private getWorkSpaceMinHeight(): number { let minHeight = this.getWorkSpaceHeight(); const workspaceContainerHeight = getOuterHeight(this.$flexContainer, true); @@ -184,32 +200,37 @@ class SchedulerTimeline extends SchedulerWorkSpace { return minHeight; } - protected override getCellCoordinatesByIndex(index) { + protected override getCellCoordinatesByIndex( + index: number, + ): { columnIndex: number; rowIndex: number } { return { columnIndex: index % this.getCellCount(), rowIndex: 0, }; } - protected override getCellElementByPosition(cellCoordinates, groupIndex) { + protected override getCellElementByPosition( + cellCoordinates: { rowIndex: number; columnIndex: number }, + groupIndex: number, + ): dxElementWrapper { const indexes = this.groupedStrategy.prepareCellIndexes(cellCoordinates, groupIndex); return this.$dateTable .find('tr') .eq(indexes.rowIndex) .find('td') - .eq(indexes.columnIndex); + .eq(indexes.columnIndex) as dxElementWrapper; } - protected override getWorkSpaceWidth() { - return getOuterWidth(this.$dateTable, true); + protected override getWorkSpaceWidth(): number { + return getOuterWidth(this.$dateTable, true) as number; } - private getIndicationFirstViewDate() { - return dateUtils.trimTime(new Date(this.getStartViewDate())); + private getIndicationFirstViewDate(): Date { + return dateUtils.trimTime(new Date(this.getStartViewDate())) as Date; } - protected override getIntervalBetween(currentDate, allDay) { + protected override getIntervalBetween(currentDate: Date, allDay?: boolean): number { const startDayHour = this.option('startDayHour'); const endDayHour = this.option('endDayHour'); const firstViewDate = this.getStartViewDate(); @@ -223,7 +244,7 @@ class SchedulerTimeline extends SchedulerWorkSpace { let tailDelta = 0; const cellCount = this.getCellCountInDay() * (fullDays - this.getWeekendsCount(fullDays)); const gapBeforeAppt = apptStart - dateUtils.trimTime(new Date(currentDate)).getTime(); - let result = cellCount * (this.option('hoursInterval') as any) * toMs('hour'); + let result = cellCount * this.option('hoursInterval') * toMs('hour'); if (!allDay) { const hour = currentDate.getHours(); @@ -256,34 +277,33 @@ class SchedulerTimeline extends SchedulerWorkSpace { return 0; } - getAllDayContainer() { + getAllDayContainer(): null { return null; } - getTimePanelWidth() { + getTimePanelWidth(): number { return 0; } // eslint-disable-next-line @typescript-eslint/no-unused-vars - getIntervalDuration(allDay) { + getIntervalDuration(allDay: boolean): number { return this.getCellDuration(); } - getCellMinWidth() { + getCellMinWidth(): number { return 0; } - getWorkSpaceLeftOffset() { + getWorkSpaceLeftOffset(): number { return 0; } - renderRAllDayPanel() {} + renderRAllDayPanel(): void {} - renderRTimeTable() {} + renderRTimeTable(): void {} - // eslint-disable-next-line @typescript-eslint/no-unused-vars - generateRenderOptions(argument?: any) { - const options = super.generateRenderOptions(true); + generateRenderOptions(isProvideVirtualCellsWidth?: boolean): ViewDataProviderOptions { + const options = super.generateRenderOptions(isProvideVirtualCellsWidth ?? true); return { ...options, @@ -296,39 +316,42 @@ class SchedulerTimeline extends SchedulerWorkSpace { // We need these methods for now but they are useless for renovation // ------------- - _init() { + _init(): void { super._init(); - (this.$element() as any).addClass(TIMELINE_CLASS); + this.$element().addClass(TIMELINE_CLASS); this.$sidebarTable = $('
') .addClass(GROUP_TABLE_CLASS); } - protected override getDefaultGroupStrategy() { + protected override getDefaultGroupStrategy(): 'vertical' { return 'vertical'; } - protected override toggleGroupingDirectionClass() { - (this.$element() as any).toggleClass(HORIZONTAL_GROUPED_WORKSPACE_CLASS, this.isHorizontalGroupedWorkSpace()); + protected override toggleGroupingDirectionClass(): void { + this.$element().toggleClass( + HORIZONTAL_GROUPED_WORKSPACE_CLASS, + this.isHorizontalGroupedWorkSpace(), + ); } - _getDefaultOptions() { + _getDefaultOptions(): TimelineDefaultOptions { return extend(super._getDefaultOptions(), { groupOrientation: 'vertical', - }); + }) as TimelineDefaultOptions; } - protected override createWorkSpaceElements() { + protected override createWorkSpaceElements(): void { this.createWorkSpaceScrollableElements(); } - protected override updateAllDayVisibility() { return noop(); } + protected override updateAllDayVisibility(): void { return noop(); } - protected override getDateHeaderTemplate() { + protected override getDateHeaderTemplate(): dxSchedulerOptions['timeCellTemplate'] { return this.option('timeCellTemplate'); } - protected override renderView() { + protected override renderView(): void { this.renderWorkSpace(); this.virtualScrollingDispatcher.updateDimensions(); @@ -343,14 +366,14 @@ class SchedulerTimeline extends SchedulerWorkSpace { this.updateHeaderEmptyCellWidth(); } - protected override setHorizontalGroupHeaderCellsHeight() { return noop(); } + protected override setHorizontalGroupHeaderCellsHeight(): void { return noop(); } - protected override getTimePanelCells() { - return (this.$element() as any) + protected override getTimePanelCells(): dxElementWrapper { + return this.$element() .find(`.${HEADER_PANEL_CELL_CLASS}:not(.${HEADER_PANEL_WEEK_CELL_CLASS})`); } - getCurrentTimePanelCellIndices() { + getCurrentTimePanelCellIndices(): number[] { const columnCountPerGroup = this.getCellCount(); const today = this.getToday(); const index = this.getCellIndexByDate(today); @@ -368,8 +391,17 @@ class SchedulerTimeline extends SchedulerWorkSpace { .map((_, groupIndex) => columnCountPerGroup * groupIndex + currentTimeColumnIndex); } - protected override renderIndicator(height, rtlOffset, $container, groupCount) { - let $indicator; + protected override renderIndicator( + height: number, + rtlOffset: number, + $container: dxElementWrapper, + groupCount: number, + ): void { + if (height !== undefined) { + noop(); + } + // eslint-disable-next-line @typescript-eslint/init-declarations + let $indicator: dxElementWrapper | undefined; const width = this.getIndicationWidth(); if (this.option('groupOrientation') === 'vertical') { @@ -377,8 +409,9 @@ class SchedulerTimeline extends SchedulerWorkSpace { setHeight($indicator, getBoundingRect($container.get(0)).height); $indicator.css('left', rtlOffset ? rtlOffset - width : width); } else { - for (let i = 0; i < groupCount; i++) { - const offset = this.isGroupedByDate() ? i * this.getCellWidth() : this.getCellCount() * this.getCellWidth() * i; + for (let i = 0; i < groupCount; i += 1) { + const offset = this.isGroupedByDate() ? i * this.getCellWidth() + : this.getCellCount() * this.getCellWidth() * i; $indicator = this.createIndicator($container); setHeight($indicator, getBoundingRect($container.get(0)).height); @@ -387,7 +420,7 @@ class SchedulerTimeline extends SchedulerWorkSpace { } } - protected override makeGroupRows(groups, groupByDate) { + protected override makeGroupRows(groups: unknown[], groupByDate: boolean): unknown { const tableCreatorStrategy = this.option('groupOrientation') === 'vertical' ? tableCreator.VERTICAL : tableCreator.HORIZONTAL; return tableCreator.makeGroupedTable( @@ -407,5 +440,6 @@ class SchedulerTimeline extends SchedulerWorkSpace { } } +// eslint-disable-next-line @typescript-eslint/no-explicit-any registerComponent('dxSchedulerTimeline', SchedulerTimeline as any); export default SchedulerTimeline; diff --git a/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline_day.ts b/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline_day.ts index 415c4a32cd01..1d905c9b4db8 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline_day.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline_day.ts @@ -6,17 +6,18 @@ import SchedulerTimeline from './m_timeline'; const TIMELINE_CLASS = 'dx-scheduler-timeline-day'; class SchedulerTimelineDay extends SchedulerTimeline { - get type() { return VIEWS.TIMELINE_DAY; } + get type(): string { return VIEWS.TIMELINE_DAY; } - protected override getElementClass() { + protected override getElementClass(): string { return TIMELINE_CLASS; } - protected override needRenderWeekHeader() { + protected override needRenderWeekHeader(): boolean { return this.isWorkSpaceWithCount(); } } +// eslint-disable-next-line @typescript-eslint/no-explicit-any registerComponent('dxSchedulerTimelineDay', SchedulerTimelineDay as any); export default SchedulerTimelineDay; diff --git a/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline_month.ts b/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline_month.ts index 96478987146a..98e20e61fa83 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline_month.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline_month.ts @@ -1,76 +1,86 @@ import registerComponent from '@js/core/component_registrator'; +import type { template } from '@js/core/templates/template'; import dateUtils from '@js/core/utils/date'; -// NOTE: Renovation component import. import { HeaderPanelComponent } from '@ts/scheduler/r1/components/index'; import { formatWeekdayAndDay, monthUtils } from '@ts/scheduler/r1/utils/index'; import { VIEWS } from '../utils/options/constants_view'; import SchedulerTimeline from './m_timeline'; +import type { ViewDataProviderOptions } from './view_model/m_types'; const TIMELINE_CLASS = 'dx-scheduler-timeline-month'; class SchedulerTimelineMonth extends SchedulerTimeline { - get type() { return VIEWS.TIMELINE_MONTH; } + get type(): string { return VIEWS.TIMELINE_MONTH; } readonly viewDirection = 'horizontal'; - get renovatedHeaderPanelComponent() { return HeaderPanelComponent; } + get renovatedHeaderPanelComponent(): typeof HeaderPanelComponent { return HeaderPanelComponent; } - protected override renderView() { + protected override renderView(): void { super.renderView(); this.updateScrollable(); } - protected override getElementClass() { + protected override getElementClass(): string { return TIMELINE_CLASS; } - protected override getDateHeaderTemplate() { + protected override getDateHeaderTemplate(): template | undefined { return this.option('dateCellTemplate'); } - protected override calculateDurationInCells(timeDiff) { + protected override calculateDurationInCells(timeDiff: number): number { return timeDiff / this.getCellDuration(); } - isIndicatorVisible() { + isIndicatorVisible(): boolean { return true; } - protected override getFormat() { + // @ts-expect-error + protected override getFormat(): (date: Date) => string { return formatWeekdayAndDay; } - protected override getIntervalBetween(currentDate) { + protected override getIntervalBetween(currentDate: Date): number { const firstViewDate = this.getStartViewDate(); const timeZoneOffset = dateUtils.getTimezonesDifference(firstViewDate, currentDate); + const startDayHour = this.option('startDayHour'); - return currentDate.getTime() - (firstViewDate.getTime() - (this.option('startDayHour') as any) * 3600000) - timeZoneOffset; + return currentDate.getTime() + - (firstViewDate.getTime() - startDayHour * 3600000) + - timeZoneOffset; } - protected override getViewStartByOptions() { + protected override getViewStartByOptions(): Date { + const currentDate: Date = this.option('currentDate') ?? new Date(); + const startDate: Date = this.option('startDate') ?? currentDate; + const firstMonthDate = dateUtils.getFirstMonthDate(startDate) ?? startDate; + return monthUtils.getViewStartByOptions( - this.option('startDate') as any, - this.option('currentDate') as any, - this.option('intervalCount') as any, - dateUtils.getFirstMonthDate(this.option('startDate') as any) as any, + startDate, + currentDate, + this.option('intervalCount'), + firstMonthDate, ); } - generateRenderOptions() { + generateRenderOptions(): ViewDataProviderOptions { const options = super.generateRenderOptions(true); return { ...options, - getDateForHeaderText: (_, date) => date, + getDateForHeaderText: (_, date: Date): Date => date, }; } - keepOriginalHours() { + keepOriginalHours(): boolean { return true; } } +// eslint-disable-next-line @typescript-eslint/no-explicit-any registerComponent('dxSchedulerTimelineMonth', SchedulerTimelineMonth as any); export default SchedulerTimelineMonth; diff --git a/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline_week.ts b/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline_week.ts index 0f38e0b3cdd5..ecf3ff4fc537 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline_week.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline_week.ts @@ -8,17 +8,18 @@ const TIMELINE_CLASS = 'dx-scheduler-timeline-week'; export default class SchedulerTimelineWeek extends SchedulerTimeline { get type() { return VIEWS.TIMELINE_WEEK; } - protected override getElementClass() { + protected override getElementClass(): string { return TIMELINE_CLASS; } - protected override needRenderWeekHeader() { + protected override needRenderWeekHeader(): boolean { return true; } - protected override incrementDate(date) { + protected override incrementDate(date: Date): void { date.setDate(date.getDate() + 1); } } +// eslint-disable-next-line @typescript-eslint/no-explicit-any registerComponent('dxSchedulerTimelineWeek', SchedulerTimelineWeek as any); 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 d83022613360..5416754cdfa2 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space.ts @@ -29,9 +29,11 @@ import { import { isDefined } from '@js/core/utils/type'; import { getWindow, hasWindow } from '@js/core/utils/window'; import type { dxSchedulerOptions } from '@js/ui/scheduler'; +import type { ScrollEvent } from '@js/ui/scroll_view'; import errors from '@js/ui/widget/ui.errors'; import Widget from '@js/ui/widget/ui.widget'; import { getMemoizeScrollTo } from '@ts/core/utils/scroll'; +import type { OptionChanged } from '@ts/core/widget/types'; import { AllDayPanelTitleComponent, AllDayTableComponent, @@ -106,6 +108,40 @@ interface RenderRWorkspaceOptions { generateNewData: boolean; } +export interface ViewDateGenerationOptions { + startDayHour: number; + endDayHour: number; + hoursInterval: number; + interval?: number; + intervalCount: number; + startViewDate: Date; + firstDayOfWeek: number; + skippedDays?: number[]; + viewOffset: number; + viewType: ViewType; +} + +export interface WorkspaceDateTableScrollableConfig { + useKeyboard: boolean; + bounceEnabled: boolean; + updateManually: boolean; + onScroll: (event: ScrollEvent) => void; + onInitialized: (args: { component: Scrollable }) => void; + onOptionChanged: (args: { fullName: string; value: unknown; component: Scrollable }) => void; + direction?: 'both'; + onEnd?: () => void; +} + +export interface WorkspaceHeaderScrollableConfig { + useKeyboard: boolean; + showScrollbar: 'never'; + direction: 'horizontal'; + useNative: false; + updateManually: true; + bounceEnabled: false; + onScroll: (event: ScrollEvent) => void; +} + const { tableCreator } = tableCreatorModule; // The constant is needed so that the dragging is not sharp. To prevent small twitches @@ -188,7 +224,7 @@ const DEFAULT_WORKSPACE_RENDER_OPTIONS: RenderRWorkspaceOptions = { generateNewData: true, }; -type WorkspaceOptionsInternal = Omit & { +export type WorkspaceOptionsInternal = Omit & { groups: ResourceLoader[]; getResourceManager: () => ResourceManager; startDate?: Date; @@ -198,6 +234,30 @@ type WorkspaceOptionsInternal = Omit & { startDayHour: number; endDayHour: number; }; + +export type WorkspaceOptionChangedOptions = WorkspaceOptionsInternal & { + onSelectionChanged?: unknown; + onSelectionEnd?: unknown; + onCellClick?: unknown; + onCellContextMenu?: unknown; + viewOffset?: number; + groupOrientation?: 'horizontal' | 'vertical'; + timeZoneCalculator?: unknown; + allDayExpanded?: boolean; + width?: number | string; + allowMultipleCellSelection?: boolean; + selectedCellData?: unknown; + scrolling?: unknown; + schedulerHeight?: number; + schedulerWidth?: number; + agendaDuration?: number | 'month'; + rowHeight?: number; + noDataText?: string; + showCurrentTimeIndicator?: boolean; + indicatorTime?: Date; + indicatorUpdateInterval?: number; + shadeUntilCurrentTime?: boolean; +}; class SchedulerWorkSpace extends Widget { private viewDataProviderValue: any; @@ -651,8 +711,8 @@ class SchedulerWorkSpace extends Widget { this.$allDayTitle = $('
').appendTo(this.$headerPanelEmptyCell); } - protected dateTableScrollableConfig() { - let config: any = { + protected dateTableScrollableConfig(): WorkspaceDateTableScrollableConfig { + let config: WorkspaceDateTableScrollableConfig = { useKeyboard: false, bounceEnabled: false, updateManually: true, @@ -665,14 +725,14 @@ class SchedulerWorkSpace extends Widget { // To prevent scroll container focus in native mode we set tabindex -1 to container // In simulated mode focusable behavior prevented by useKeyboard: false private option onInitialized: ({ component }) => { - const useKeyboardDisabled = component.option('useKeyboard') === false; - const useNativeEnabled = component.option('useNative') === true; + const useKeyboardDisabled = component.option('useKeyboard'); + const useNativeEnabled = component.option('useNative'); if (useKeyboardDisabled && useNativeEnabled) { $(component.container()).attr('tabindex', -1); } }, onOptionChanged: ({ fullName, value, component }) => { - const useKeyboardDisabled = component.option('useKeyboard') === false; + const useKeyboardDisabled = component.option('useKeyboard'); if (useKeyboardDisabled && fullName === 'useNative' && value === true) { $(component.container()).attr('tabindex', -1); } @@ -689,7 +749,7 @@ class SchedulerWorkSpace extends Widget { const currentOnScroll = config.onScroll; config = { ...config, - onScroll: (e) => { + onScroll: (e: ScrollEvent) => { currentOnScroll?.(e); this.virtualScrollingDispatcher.handleOnScrollEvent(e?.scrollOffset); @@ -700,14 +760,24 @@ class SchedulerWorkSpace extends Widget { return config; } - protected createCrossScrollingConfig({ onScroll }): any { + protected createCrossScrollingConfig( + { onScroll }: Pick, + ): Pick { return { direction: 'both', - onScroll: (event) => { - onScroll?.(); + onScroll: (event: ScrollEvent) => { + onScroll?.(event); + + const top = event.scrollOffset?.top; + const left = event.scrollOffset?.left; + + if (top !== undefined) { + this.scrollSync.sidebar({ top }); + } - this.scrollSync.sidebar({ top: event.scrollOffset.top }); - this.scrollSync.header({ left: event.scrollOffset.left }); + if (left !== undefined) { + this.scrollSync.header({ left }); + } }, onEnd: () => { (this.option('onScrollEnd') as any)(); @@ -715,7 +785,7 @@ class SchedulerWorkSpace extends Widget { }; } - protected headerScrollableConfig() { + protected headerScrollableConfig(): WorkspaceHeaderScrollableConfig { return { useKeyboard: false, showScrollbar: 'never', @@ -723,7 +793,7 @@ class SchedulerWorkSpace extends Widget { useNative: false, updateManually: true, bounceEnabled: false, - onScroll: (event) => { + onScroll: (event: ScrollEvent) => { this.scrollSync.dateTable({ left: event.scrollOffset.left }); }, }; @@ -852,14 +922,14 @@ class SchedulerWorkSpace extends Widget { ); } - generateRenderOptions(isProvideVirtualCellsWidth?: any): ViewDataProviderOptions { + generateRenderOptions(isProvideVirtualCellsWidth = false): ViewDataProviderOptions { const groupCount = this.getGroupCount(); const groupOrientation = groupCount > 0 ? this.option('groupOrientation') : this.getDefaultGroupStrategy(); - const options = { + const options: ViewDataProviderOptions = { groupByDate: this.option('groupByDate'), startRowIndex: 0, startCellIndex: 0, @@ -1274,7 +1344,8 @@ class SchedulerWorkSpace extends Widget { }; } - protected getDateGenerationOptions() { + protected getDateGenerationOptions(): ViewDateGenerationOptions { + // @ts-expect-error return { startDayHour: this.option('startDayHour'), endDayHour: this.option('endDayHour'), @@ -2247,9 +2318,9 @@ class SchedulerWorkSpace extends Widget { this.virtualScrollingDispatcher.dispose(); } - _getDefaultOptions() { + _getDefaultOptions(): WorkspaceOptionsInternal { // @ts-expect-error - return extend(super._getDefaultOptions(), { + const defaultOptions = extend(super._getDefaultOptions(), { currentDate: new Date(), intervalCount: 1, startDate: null, @@ -2282,18 +2353,20 @@ class SchedulerWorkSpace extends Widget { allDayPanelMode: 'all', height: undefined, draggingMode: 'outlook', - onScrollEnd: () => {}, + onScrollEnd: noop, getHeaderHeight: undefined, - renderAppointments: () => {}, - onShowAllDayPanel: () => {}, - onSelectedCellsClick: () => {}, + renderAppointments: noop, + onShowAllDayPanel: noop, + onSelectedCellsClick: noop, timeZoneCalculator: undefined, schedulerHeight: undefined, schedulerWidth: undefined, }); + + return defaultOptions; } - _optionChanged(args) { + _optionChanged(args: OptionChanged): void { switch (args.name) { case 'startDayHour': case 'endDayHour': diff --git a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_day.ts b/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_day.ts index 1d6c689f2c7b..d36bd53066c9 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_day.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_day.ts @@ -6,13 +6,13 @@ import SchedulerWorkSpaceVertical from './m_work_space_vertical'; const DAY_CLASS = 'dx-scheduler-work-space-day'; class SchedulerWorkSpaceDay extends SchedulerWorkSpaceVertical { - get type() { return VIEWS.DAY; } + get type(): string { return VIEWS.DAY; } - protected override getElementClass() { + protected override getElementClass(): string { return DAY_CLASS; } - renderRHeaderPanel() { + renderRHeaderPanel(): void { if (this.option('intervalCount') === 1) { super.renderRHeaderPanel(false); } else { @@ -21,6 +21,7 @@ class SchedulerWorkSpaceDay extends SchedulerWorkSpaceVertical { } } +// eslint-disable-next-line @typescript-eslint/no-explicit-any registerComponent('dxSchedulerWorkSpaceDay', SchedulerWorkSpaceDay as any); export default SchedulerWorkSpaceDay; diff --git a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_indicator.ts b/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_indicator.ts index 3f9f92ffd70e..cb0ded125278 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_indicator.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_indicator.ts @@ -1,23 +1,34 @@ import registerComponent from '@js/core/component_registrator'; -import $ from '@js/core/renderer'; +import $, { type dxElementWrapper } from '@js/core/renderer'; import dateUtils from '@js/core/utils/date'; import { extend } from '@js/core/utils/extend'; import { getBoundingRect } from '@js/core/utils/position'; import { setWidth } from '@js/core/utils/size'; import { hasWindow } from '@js/core/utils/window'; import { dateUtilsTs } from '@ts/core/utils/date'; +import type { OptionChanged } from '@ts/core/widget/types'; import { getToday } from '@ts/scheduler/r1/utils/index'; import { HEADER_CURRENT_TIME_CELL_CLASS } from '../m_classes'; import timezoneUtils from '../m_utils_time_zone'; -import SchedulerWorkSpace from './m_work_space'; +import SchedulerWorkSpace, { + type WorkspaceOptionChangedOptions, + type WorkspaceOptionsInternal, +} from './m_work_space'; const toMs = dateUtils.dateToMilliseconds; const SCHEDULER_DATE_TIME_INDICATOR_CLASS = 'dx-scheduler-date-time-indicator'; +export interface WorkSpaceIndicatorDefaultOptions extends WorkspaceOptionsInternal { + showCurrentTimeIndicator: boolean; + indicatorTime: Date; + indicatorUpdateInterval: number; + shadeUntilCurrentTime: boolean; +} + class SchedulerWorkSpaceIndicator extends SchedulerWorkSpace { - private indicatorInterval: any; + private indicatorInterval?: ReturnType; protected getToday(): Date { const viewOffset = this.option('viewOffset') as number; @@ -35,7 +46,7 @@ class SchedulerWorkSpaceIndicator extends SchedulerWorkSpace { return false; } - isIndicationAvailable() { + isIndicationAvailable(): boolean { if (!hasWindow()) { return false; } @@ -45,7 +56,7 @@ class SchedulerWorkSpaceIndicator extends SchedulerWorkSpace { return today >= dateUtils.trimTime(new Date(this.getStartViewDate())); } - isIndicatorVisible() { + isIndicatorVisible(): boolean { const today = this.getToday(); // Subtracts 1 ms from the real endViewDate instead of 1 minute @@ -57,10 +68,15 @@ class SchedulerWorkSpaceIndicator extends SchedulerWorkSpace { return dateUtils.dateInRange(today, firstViewDate, endViewDate); } - protected renderIndicator(height, rtlOffset, $container, groupCount) { + protected renderIndicator( + height: number, + rtlOffset: number, + $container: dxElementWrapper, + groupCount: number, + ): void { const groupedByDate = this.isGroupedByDate(); const repeatCount = groupedByDate ? 1 : groupCount; - for (let i = 0; i < repeatCount; i++) { + Array.from({ length: repeatCount }).forEach((_, i) => { const $indicator = this.createIndicator($container); setWidth( @@ -68,44 +84,53 @@ class SchedulerWorkSpaceIndicator extends SchedulerWorkSpace { groupedByDate ? this.getCellWidth() * groupCount : this.getCellWidth(), ); this.groupedStrategy.shiftIndicator($indicator, height, rtlOffset, i); - } + }); } - protected createIndicator($container) { + protected createIndicator($container: dxElementWrapper): dxElementWrapper { const $indicator = $('
').addClass(SCHEDULER_DATE_TIME_INDICATOR_CLASS); $container.append($indicator); return $indicator; } - private getRtlOffset(width) { + private getRtlOffset(width: number): number { return this.option('rtlEnabled') ? getBoundingRect(this.$dateTableScrollable.$content().get(0)).width - this.getTimePanelWidth() - width : 0; } - protected setIndicationUpdateInterval() { + protected setIndicationUpdateInterval(): void { if (!this.option('showCurrentTimeIndicator') || this.option('indicatorUpdateInterval') === 0) { return; } this.clearIndicatorUpdateInterval(); - this.indicatorInterval = setInterval(() => { + const scheduleIndicatorUpdate = (): void => { this.renderCurrentDateTimeIndication(); - }, this.option('indicatorUpdateInterval')); + this.indicatorInterval = setTimeout( + scheduleIndicatorUpdate, + this.option('indicatorUpdateInterval'), + ); + }; + + this.indicatorInterval = setTimeout( + scheduleIndicatorUpdate, + this.option('indicatorUpdateInterval'), + ); } - private clearIndicatorUpdateInterval() { + private clearIndicatorUpdateInterval(): void { if (this.indicatorInterval) { - clearInterval(this.indicatorInterval); - delete this.indicatorInterval; + clearTimeout(this.indicatorInterval); + this.indicatorInterval = undefined; } } - protected isVerticalShader() { + protected isVerticalShader(): boolean { return true; } - getIndicationWidth() { + getIndicationWidth(): number { const cellCount = this.getCellCount(); const cellSpan = Math.min(this.getIndicatorDaysSpan(), cellCount); const width = cellSpan * this.getCellWidth(); @@ -114,7 +139,7 @@ class SchedulerWorkSpaceIndicator extends SchedulerWorkSpace { return Math.min(width, maxWidth); } - getIndicatorOffset() { + getIndicatorOffset(): number { const cellSpan = this.getIndicatorDaysSpan() - 1; const offset = cellSpan * this.getCellWidth(); @@ -134,7 +159,7 @@ class SchedulerWorkSpaceIndicator extends SchedulerWorkSpace { return Math.ceil((timeDiff + 1) / toMs('day')); } - getIndicationHeight() { + getIndicationHeight(): number { const today = timezoneUtils.getDateWithoutTimezoneChange(this.getToday()); const cellHeight = this.getCellHeight(); const date = new Date(this.getStartViewDate()); @@ -149,9 +174,9 @@ class SchedulerWorkSpaceIndicator extends SchedulerWorkSpace { return cellCount * cellHeight; } - _dispose() { + _dispose(): void { this.clearIndicatorUpdateInterval(); - super._dispose.apply(this, arguments as any); + super._dispose(); } renderCurrentDateTimeIndication(): void { @@ -183,8 +208,8 @@ class SchedulerWorkSpaceIndicator extends SchedulerWorkSpace { return false; } - protected override getHeaderPanelCellClass(i) { - const cellClass = super.getHeaderPanelCellClass(i); + protected override getHeaderPanelCellClass(i: number): string { + const cellClass = super.getHeaderPanelCellClass(i) as string; if (this.isCurrentTimeHeaderCell(i)) { return `${cellClass} ${HEADER_CURRENT_TIME_CELL_CLASS}`; @@ -193,30 +218,30 @@ class SchedulerWorkSpaceIndicator extends SchedulerWorkSpace { return cellClass; } - protected override cleanView() { + protected override cleanView(): void { super.cleanView(); this.cleanDateTimeIndicator(); } - _dimensionChanged() { + _dimensionChanged(): void { super._dimensionChanged(); this.renderCurrentDateTimeLineAndShader(); } - private cleanDateTimeIndicator() { - (this.$element() as any).find(`.${SCHEDULER_DATE_TIME_INDICATOR_CLASS}`).remove(); + private cleanDateTimeIndicator(): void { + this.$element().find(`.${SCHEDULER_DATE_TIME_INDICATOR_CLASS}`).remove(); } - protected override cleanWorkSpace() { + protected override cleanWorkSpace(): void { super.cleanWorkSpace(); this.renderDateTimeIndication(); this.setIndicationUpdateInterval(); } - _optionChanged(args) { + _optionChanged(args: OptionChanged): void { switch (args.name) { case 'showCurrentTimeIndicator': case 'indicatorTime': @@ -239,16 +264,16 @@ class SchedulerWorkSpaceIndicator extends SchedulerWorkSpace { } } - _getDefaultOptions() { + _getDefaultOptions(): WorkSpaceIndicatorDefaultOptions { return extend(super._getDefaultOptions(), { showCurrentTimeIndicator: true, indicatorTime: new Date(), indicatorUpdateInterval: 5 * toMs('minute'), shadeUntilCurrentTime: true, - }); + }) as WorkSpaceIndicatorDefaultOptions; } - protected getCurrentTimePanelCellIndices() { + protected getCurrentTimePanelCellIndices(): number[] { const rowCountPerGroup = this.getTimePanelRowCount(); const today = this.getToday(); const index = this.getCellIndexByDate(today); @@ -258,10 +283,9 @@ class SchedulerWorkSpaceIndicator extends SchedulerWorkSpace { return []; } - let cellIndices; - if (currentTimeRowIndex === 0) { - cellIndices = [currentTimeRowIndex]; - } else { + let cellIndices: number[] = [currentTimeRowIndex]; + + if (currentTimeRowIndex !== 0) { cellIndices = currentTimeRowIndex % 2 === 0 ? [currentTimeRowIndex - 1, currentTimeRowIndex] : [currentTimeRowIndex, currentTimeRowIndex + 1]; @@ -272,7 +296,7 @@ class SchedulerWorkSpaceIndicator extends SchedulerWorkSpace { : 1; return [...new Array(verticalGroupCount)] - .reduce((currentIndices, _, groupIndex) => [ + .reduce((currentIndices, _, groupIndex) => [ ...currentIndices, ...cellIndices.map((cellIndex) => rowCountPerGroup * groupIndex + cellIndex), ], []); @@ -304,5 +328,6 @@ class SchedulerWorkSpaceIndicator extends SchedulerWorkSpace { } } +// eslint-disable-next-line @typescript-eslint/no-explicit-any registerComponent('dxSchedulerWorkSpace', SchedulerWorkSpaceIndicator as any); export default SchedulerWorkSpaceIndicator; diff --git a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_month.ts b/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_month.ts index 7585eb598a71..f53be27fa317 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_month.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_month.ts @@ -3,12 +3,12 @@ import { noop } from '@js/core/utils/common'; import dateUtils from '@js/core/utils/date'; import { getBoundingRect } from '@js/core/utils/position'; import { hasWindow } from '@js/core/utils/window'; -// NOTE: Renovation component import. import { DateTableMonthComponent } from '@ts/scheduler/r1/components/index'; import { formatWeekday, monthUtils } from '@ts/scheduler/r1/utils/index'; import { utils } from '../m_utils'; import { VIEWS } from '../utils/options/constants_view'; +import type { ViewDateGenerationOptions } from './m_work_space'; import SchedulerWorkSpace from './m_work_space_indicator'; const MONTH_CLASS = 'dx-scheduler-work-space-month'; @@ -16,24 +16,28 @@ const MONTH_CLASS = 'dx-scheduler-work-space-month'; const toMs = dateUtils.dateToMilliseconds; class SchedulerWorkSpaceMonth extends SchedulerWorkSpace { - get type() { return VIEWS.MONTH; } + get type(): string { return VIEWS.MONTH; } - protected override getElementClass() { + protected override getElementClass(): string { return MONTH_CLASS; } - protected override getFormat() { + protected override getFormat(): (date: Date) => string { return formatWeekday; } - protected override getIntervalBetween(currentDate) { + protected override getIntervalBetween(currentDate: Date): number { const firstViewDate = this.getStartViewDate(); const timeZoneOffset = dateUtils.getTimezonesDifference(firstViewDate, currentDate); + const startDayHour = this.option('startDayHour'); - return currentDate.getTime() - (firstViewDate.getTime() - (this.option('startDayHour') as any) * 3600000) - timeZoneOffset; + return currentDate.getTime() + - (firstViewDate.getTime() - startDayHour * 3600000) + - timeZoneOffset; } - protected override getDateGenerationOptions() { + protected override getDateGenerationOptions(): ViewDateGenerationOptions + & { cellCountInDay: number } { return { ...super.getDateGenerationOptions(), cellCountInDay: 1, @@ -45,8 +49,8 @@ class SchedulerWorkSpaceMonth extends SchedulerWorkSpace { * getCellWidth method need remove. Details in T712431 there is a test for this bug, * when changing the layout, the test will also be useless */ - getCellWidth() { - return this.cache.memo('cellWidth', () => { + getCellWidth(): number | undefined { + const cellWidth = this.cache.memo('cellWidth', (): number | undefined => { const DAYS_IN_WEEK = 7; let averageWidth = 0; @@ -57,13 +61,17 @@ class SchedulerWorkSpaceMonth extends SchedulerWorkSpace { return cells.length === 0 ? undefined : averageWidth / DAYS_IN_WEEK; }); + + return cellWidth as number | undefined; } - protected override insertAllDayRowsIntoDateTable() { + protected override insertAllDayRowsIntoDateTable(): boolean { return false; } - protected override getCellCoordinatesByIndex(index) { + protected override getCellCoordinatesByIndex( + index: number, + ): { rowIndex: number; columnIndex: number } { const rowIndex = Math.floor(index / this.getCellCount()); const columnIndex = index - this.getCellCount() * rowIndex; @@ -73,61 +81,64 @@ class SchedulerWorkSpaceMonth extends SchedulerWorkSpace { }; } - protected override needCreateCrossScrolling() { - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - return this.option('crossScrollingEnabled') || this.isVerticalGroupedWorkSpace(); + protected override needCreateCrossScrolling(): boolean { + return this.option('crossScrollingEnabled') ?? this.isVerticalGroupedWorkSpace(); } - protected override getViewStartByOptions() { + protected override getViewStartByOptions(): Date { + const currentDate: Date = this.option('currentDate') ?? new Date(); + const startDate: Date = this.option('startDate') ?? currentDate; + const firstMonthDate = dateUtils.getFirstMonthDate(startDate) ?? startDate; + return monthUtils.getViewStartByOptions( - this.option('startDate') as any, - this.option('currentDate') as any, - this.option('intervalCount') as any, - dateUtils.getFirstMonthDate(this.option('startDate')) as any, + startDate, + currentDate, + this.option('intervalCount'), + firstMonthDate, ); } - protected override updateIndex(index) { + protected override updateIndex(index: number): number { return index; } - isIndicationAvailable() { + isIndicationAvailable(): boolean { return false; } - getIntervalDuration() { + getIntervalDuration(): number { return toMs('day'); } - getTimePanelWidth() { + getTimePanelWidth(): number { return 0; } - supportAllDayRow() { + supportAllDayRow(): boolean { return false; } - keepOriginalHours() { + keepOriginalHours(): boolean { return true; } - getWorkSpaceLeftOffset() { + getWorkSpaceLeftOffset(): number { return 0; } - needApplyCollectorOffset() { + needApplyCollectorOffset(): boolean { return true; } - protected override getHeaderDate() { + protected override getHeaderDate(): Date { return this.getViewStartByOptions(); } - renderRAllDayPanel() {} + renderRAllDayPanel(): void {} - renderRTimeTable() {} + renderRTimeTable(): void {} - renderRDateTable() { + renderRDateTable(): void { utils.renovation.renderComponent( this, this.$dateTable, @@ -141,7 +152,7 @@ class SchedulerWorkSpaceMonth extends SchedulerWorkSpace { // We need these methods for now but they are useless for renovation // ------------- - protected override createWorkSpaceElements() { + protected override createWorkSpaceElements(): void { if (this.isVerticalGroupedWorkSpace()) { this.createWorkSpaceScrollableElements(); } else { @@ -149,9 +160,10 @@ class SchedulerWorkSpaceMonth extends SchedulerWorkSpace { } } - protected override updateAllDayVisibility() { return noop(); } + protected override updateAllDayVisibility(): void { return noop(); } } +// eslint-disable-next-line @typescript-eslint/no-explicit-any registerComponent('dxSchedulerWorkSpaceMonth', SchedulerWorkSpaceMonth as any); export default SchedulerWorkSpaceMonth; diff --git a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_week.ts b/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_week.ts index e756a49ad902..3e825a8ce712 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_week.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_week.ts @@ -8,15 +8,16 @@ const WEEK_CLASS = 'dx-scheduler-work-space-week'; class SchedulerWorkSpaceWeek extends SchedulerWorkSpaceVertical { get type() { return VIEWS.WEEK; } - protected override getElementClass() { + protected override getElementClass(): string { return WEEK_CLASS; } - protected override calculateViewStartDate() { - return weekUtils.calculateViewStartDate(this.option('startDate') as any, this.firstDayOfWeek()); + protected override calculateViewStartDate(): Date { + return weekUtils.calculateViewStartDate(this.option('startDate') as Date, this.firstDayOfWeek()); } } +// eslint-disable-next-line @typescript-eslint/no-explicit-any registerComponent('dxSchedulerWorkSpaceWeek', SchedulerWorkSpaceWeek as any); export default SchedulerWorkSpaceWeek; From 7f1d1c116411090525d0325b7f1fab3ca4cbe183 Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Tue, 2 Jun 2026 13:35:40 +0200 Subject: [PATCH 02/21] fix: small fixes --- .../scheduler/workspaces/m_agenda.ts | 1 - .../scheduler/workspaces/m_work_space.ts | 6 +++--- .../workspaces/m_work_space_indicator.ts | 18 +++++------------- .../scheduler/workspaces/m_work_space_month.ts | 12 ++++-------- 4 files changed, 12 insertions(+), 25 deletions(-) diff --git a/packages/devextreme/js/__internal/scheduler/workspaces/m_agenda.ts b/packages/devextreme/js/__internal/scheduler/workspaces/m_agenda.ts index 56d06698a036..8002145efdab 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_agenda.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/m_agenda.ts @@ -208,7 +208,6 @@ class SchedulerAgenda extends WorkSpace { protected override createCrossScrollingConfig(): Pick { return { - direction: 'both', onScroll: noop, onEnd: noop, }; 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 5416754cdfa2..3c816e3e0eea 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space.ts @@ -725,14 +725,14 @@ class SchedulerWorkSpace extends Widget { // To prevent scroll container focus in native mode we set tabindex -1 to container // In simulated mode focusable behavior prevented by useKeyboard: false private option onInitialized: ({ component }) => { - const useKeyboardDisabled = component.option('useKeyboard'); - const useNativeEnabled = component.option('useNative'); + const useKeyboardDisabled = !(component.option('useKeyboard') as unknown as boolean); + const useNativeEnabled = component.option('useNative') as unknown as boolean; if (useKeyboardDisabled && useNativeEnabled) { $(component.container()).attr('tabindex', -1); } }, onOptionChanged: ({ fullName, value, component }) => { - const useKeyboardDisabled = component.option('useKeyboard'); + const useKeyboardDisabled = !(component.option('useKeyboard') as unknown as boolean); if (useKeyboardDisabled && fullName === 'useNative' && value === true) { $(component.container()).attr('tabindex', -1); } diff --git a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_indicator.ts b/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_indicator.ts index cb0ded125278..4fe81a5c2c27 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_indicator.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_indicator.ts @@ -105,24 +105,16 @@ class SchedulerWorkSpaceIndicator extends SchedulerWorkSpace { this.clearIndicatorUpdateInterval(); - const scheduleIndicatorUpdate = (): void => { + // eslint-disable-next-line no-restricted-globals + this.indicatorInterval = setInterval(() => { this.renderCurrentDateTimeIndication(); - this.indicatorInterval = setTimeout( - scheduleIndicatorUpdate, - this.option('indicatorUpdateInterval'), - ); - }; - - this.indicatorInterval = setTimeout( - scheduleIndicatorUpdate, - this.option('indicatorUpdateInterval'), - ); + }, this.option('indicatorUpdateInterval')); } private clearIndicatorUpdateInterval(): void { if (this.indicatorInterval) { - clearTimeout(this.indicatorInterval); - this.indicatorInterval = undefined; + clearInterval(this.indicatorInterval); + delete this.indicatorInterval; } } diff --git a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_month.ts b/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_month.ts index f53be27fa317..3f48e543ac2e 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_month.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_month.ts @@ -82,19 +82,15 @@ class SchedulerWorkSpaceMonth extends SchedulerWorkSpace { } protected override needCreateCrossScrolling(): boolean { - return this.option('crossScrollingEnabled') ?? this.isVerticalGroupedWorkSpace(); + return this.option('crossScrollingEnabled') || this.isVerticalGroupedWorkSpace(); } protected override getViewStartByOptions(): Date { - const currentDate: Date = this.option('currentDate') ?? new Date(); - const startDate: Date = this.option('startDate') ?? currentDate; - const firstMonthDate = dateUtils.getFirstMonthDate(startDate) ?? startDate; - return monthUtils.getViewStartByOptions( - startDate, - currentDate, + this.option('startDate'), + this.option('currentDate'), this.option('intervalCount'), - firstMonthDate, + dateUtils.getFirstMonthDate(this.option('startDate')) as Date, ); } From 9abbd26720b5190c98590a8e49b8cd81057449e0 Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Wed, 3 Jun 2026 11:35:51 +0200 Subject: [PATCH 03/21] refactor: changes --- packages/devextreme/js/__internal/scheduler/m_scheduler.ts | 5 +++-- .../js/__internal/scheduler/workspaces/m_work_space.ts | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/devextreme/js/__internal/scheduler/m_scheduler.ts b/packages/devextreme/js/__internal/scheduler/m_scheduler.ts index 42c8595262a3..bb33fca7b71d 100644 --- a/packages/devextreme/js/__internal/scheduler/m_scheduler.ts +++ b/packages/devextreme/js/__internal/scheduler/m_scheduler.ts @@ -33,6 +33,7 @@ import type { } from '@js/ui/scheduler'; import errors from '@js/ui/widget/ui.errors'; import { dateUtilsTs } from '@ts/core/utils/date'; +import type { OptionChanged } from '@ts/core/widget/types'; import { createA11yStatusContainer } from './a11y_status/a11y_status_render'; import { getA11yStatusText } from './a11y_status/a11y_status_text'; @@ -79,7 +80,7 @@ import type { IFieldExpr } from './utils/index'; 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 type { NormalizedView, SafeSchedulerOptions } from './utils/options/types'; 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'; @@ -268,7 +269,7 @@ class Scheduler extends SchedulerOptionsBaseWidget { return resolveCallbacks.promise(); } - _optionChanged(args) { + _optionChanged(args: OptionChanged): void { this.schedulerOptionChanged(args); const { value, name } = args; 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 3c816e3e0eea..f92459a7c7d7 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space.ts @@ -28,7 +28,6 @@ import { } from '@js/core/utils/size'; import { isDefined } from '@js/core/utils/type'; import { getWindow, hasWindow } from '@js/core/utils/window'; -import type { dxSchedulerOptions } from '@js/ui/scheduler'; import type { ScrollEvent } from '@js/ui/scroll_view'; import errors from '@js/ui/widget/ui.errors'; import Widget from '@js/ui/widget/ui.widget'; @@ -74,6 +73,7 @@ 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 type { SafeSchedulerOptions } from '../utils/options/types'; import { getAppointmentGroupIndex, getSafeGroupValues, @@ -224,7 +224,7 @@ const DEFAULT_WORKSPACE_RENDER_OPTIONS: RenderRWorkspaceOptions = { generateNewData: true, }; -export type WorkspaceOptionsInternal = Omit & { +export type WorkspaceOptionsInternal = Omit & { groups: ResourceLoader[]; getResourceManager: () => ResourceManager; startDate?: Date; @@ -258,6 +258,7 @@ export type WorkspaceOptionChangedOptions = WorkspaceOptionsInternal & { indicatorUpdateInterval?: number; shadeUntilCurrentTime?: boolean; }; + class SchedulerWorkSpace extends Widget { private viewDataProviderValue: any; From b5dd7d6fb9169134acba368c418c1753ffb7ed45 Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Wed, 3 Jun 2026 12:16:21 +0200 Subject: [PATCH 04/21] fix: fix build --- .../devextreme/js/__internal/scheduler/workspaces/m_agenda.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/devextreme/js/__internal/scheduler/workspaces/m_agenda.ts b/packages/devextreme/js/__internal/scheduler/workspaces/m_agenda.ts index 8002145efdab..57482b10676a 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_agenda.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/m_agenda.ts @@ -197,7 +197,7 @@ class SchedulerAgenda extends WorkSpace { private renderNoData(): void { this.$noDataContainer = $('
').addClass(NODATA_CONTAINER_CLASS) - .html(this.option('noDataText') as string); + .html(this.option('noDataText')); this.$dateTableScrollable.$content().append(this.$noDataContainer); } From 4ef5345d57705c7286420be4a599119ad4f496bb Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Wed, 3 Jun 2026 13:42:04 +0200 Subject: [PATCH 05/21] fix: copilot review --- .../scheduler/workspaces/m_agenda.ts | 24 +++++-------------- .../scheduler/workspaces/m_timeline.ts | 8 +------ .../scheduler/workspaces/m_timeline_month.ts | 1 - .../scheduler/workspaces/m_work_space.ts | 21 +++++++++------- .../workspaces/m_work_space_indicator.ts | 4 ++-- 5 files changed, 21 insertions(+), 37 deletions(-) diff --git a/packages/devextreme/js/__internal/scheduler/workspaces/m_agenda.ts b/packages/devextreme/js/__internal/scheduler/workspaces/m_agenda.ts index 57482b10676a..7b1c068b1ff0 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_agenda.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/m_agenda.ts @@ -24,7 +24,7 @@ import { VIEWS } from '../utils/options/constants_view'; import { reduceResourcesTree } from '../utils/resource_manager/agenda_group_utils'; import type { GroupNode } from '../utils/resource_manager/types'; import type { ListEntity } from '../view_model/types'; -import WorkSpace, { type WorkspaceDateTableScrollableConfig, type WorkspaceOptionChangedOptions, type WorkspaceOptionsInternal } from './m_work_space'; +import WorkSpace, { type WorkspaceOptionChangedOptions, type WorkspaceOptionsInternal } from './m_work_space'; const { tableCreator } = tableCreatorModule; @@ -391,11 +391,9 @@ class SchedulerAgenda extends WorkSpace { protected renderTableBody( options: AgendaRenderOptions, + // eslint-disable-next-line @typescript-eslint/no-unused-vars delayCellTemplateRendering?: unknown, ): void { - if (delayCellTemplateRendering) { - noop(); - } const cellTemplates: unknown[] = []; const cellTemplateOpt = options.cellTemplate as { render?: (templateOptions: unknown) => unknown; @@ -445,7 +443,7 @@ class SchedulerAgenda extends WorkSpace { }; for (i = 0; i < this.rows.length; i += 1) { - each(this.rows[i], fillTableBody.bind(this)); + each(this.rows[i], fillTableBody); this.setLastRowClass(); } @@ -529,22 +527,12 @@ class SchedulerAgenda extends WorkSpace { updateScrollPosition(date: Date): void { const newDate = this.timeZoneCalculator.createDate(date, 'toGrid'); - const bounds = this.getVisibleBounds(); - - if (this.needUpdateScrollPosition(newDate, bounds)) { + if (this.needUpdateScrollPosition(newDate)) { this.scrollTo(newDate); } } - needUpdateScrollPosition( - date: Date, - appointmentGroupValues?: unknown, - inAllDayRow?: boolean, - ): boolean { - if (appointmentGroupValues || inAllDayRow) { - noop(); - } - + override needUpdateScrollPosition(date: Date): boolean { const bounds = this.getVisibleBounds(); const hours = date.getHours(); const minutes = date.getMinutes(); @@ -558,7 +546,7 @@ class SchedulerAgenda extends WorkSpace { isUpdateNeeded = true; } - if (hours === bounds.bottom.hours && minutes > bounds.top.minutes) { + if (hours === bounds.bottom.hours && minutes > bounds.bottom.minutes) { isUpdateNeeded = true; } diff --git a/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline.ts b/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline.ts index 861a32b40a8b..b39d3cab8061 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline.ts @@ -56,12 +56,9 @@ class SchedulerTimeline extends SchedulerWorkSpace { protected override getTotalRowCount( groupCount: number, + // eslint-disable-next-line @typescript-eslint/no-unused-vars includeAllDayPanelRows?: unknown, ): number { - if (includeAllDayPanelRows !== undefined) { - noop(); - } - if (this.isHorizontalGroupedWorkSpace()) { return this.getRowCount(); } @@ -397,9 +394,6 @@ class SchedulerTimeline extends SchedulerWorkSpace { $container: dxElementWrapper, groupCount: number, ): void { - if (height !== undefined) { - noop(); - } // eslint-disable-next-line @typescript-eslint/init-declarations let $indicator: dxElementWrapper | undefined; const width = this.getIndicationWidth(); diff --git a/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline_month.ts b/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline_month.ts index 98e20e61fa83..da37cfd36648 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline_month.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline_month.ts @@ -39,7 +39,6 @@ class SchedulerTimelineMonth extends SchedulerTimeline { return true; } - // @ts-expect-error protected override getFormat(): (date: Date) => string { return formatWeekdayAndDay; } 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 f92459a7c7d7..f9d4e4835560 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space.ts @@ -10,6 +10,7 @@ import { import pointerEvents from '@js/common/core/events/pointer'; import { addNamespace, isMouseEvent } from '@js/common/core/events/utils/index'; import domAdapter from '@js/core/dom_adapter'; +import type { OptionChangedEventInfo } from '@js/core/dom_component'; import { getPublicElement } from '@js/core/element'; import type { dxElementWrapper } from '@js/core/renderer'; import $ from '@js/core/renderer'; @@ -28,6 +29,7 @@ import { } from '@js/core/utils/size'; import { isDefined } from '@js/core/utils/type'; import { getWindow, hasWindow } from '@js/core/utils/window'; +import type { InitializedEventInfo } from '@js/events'; import type { ScrollEvent } from '@js/ui/scroll_view'; import errors from '@js/ui/widget/ui.errors'; import Widget from '@js/ui/widget/ui.widget'; @@ -126,9 +128,9 @@ export interface WorkspaceDateTableScrollableConfig { bounceEnabled: boolean; updateManually: boolean; onScroll: (event: ScrollEvent) => void; - onInitialized: (args: { component: Scrollable }) => void; - onOptionChanged: (args: { fullName: string; value: unknown; component: Scrollable }) => void; - direction?: 'both'; + onInitialized: (args: InitializedEventInfo) => void; + onOptionChanged: (args: OptionChangedEventInfo) => void; + direction?: 'horizontal' | 'vertical' | 'both'; onEnd?: () => void; } @@ -139,6 +141,7 @@ export interface WorkspaceHeaderScrollableConfig { useNative: false; updateManually: true; bounceEnabled: false; + scrollByContent?: boolean; onScroll: (event: ScrollEvent) => void; } @@ -250,7 +253,7 @@ export type WorkspaceOptionChangedOptions = WorkspaceOptionsInternal & { scrolling?: unknown; schedulerHeight?: number; schedulerWidth?: number; - agendaDuration?: number | 'month'; + agendaDuration?: number; rowHeight?: number; noDataText?: string; showCurrentTimeIndicator?: boolean; @@ -726,14 +729,14 @@ class SchedulerWorkSpace extends Widget { // To prevent scroll container focus in native mode we set tabindex -1 to container // In simulated mode focusable behavior prevented by useKeyboard: false private option onInitialized: ({ component }) => { - const useKeyboardDisabled = !(component.option('useKeyboard') as unknown as boolean); - const useNativeEnabled = component.option('useNative') as unknown as boolean; + const useKeyboardDisabled = (component?.option('useKeyboard') as unknown as boolean | undefined) === false; + const useNativeEnabled = (component?.option('useNative') as unknown as boolean | undefined) === true; if (useKeyboardDisabled && useNativeEnabled) { - $(component.container()).attr('tabindex', -1); + $(component?.container()).attr('tabindex', -1); } }, onOptionChanged: ({ fullName, value, component }) => { - const useKeyboardDisabled = !(component.option('useKeyboard') as unknown as boolean); + const useKeyboardDisabled = (component.option('useKeyboard') as unknown as boolean | undefined) === false; if (useKeyboardDisabled && fullName === 'useNative' && value === true) { $(component.container()).attr('tabindex', -1); } @@ -1289,7 +1292,7 @@ class SchedulerWorkSpace extends Widget { }); } - protected getFormat() { return abstract(); } + protected getFormat(): string | ((date: Date) => string) { return abstract(); } getWorkArea() { return this.$dateTableContainer; diff --git a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_indicator.ts b/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_indicator.ts index 4fe81a5c2c27..46b9f0746084 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_indicator.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_indicator.ts @@ -76,7 +76,7 @@ class SchedulerWorkSpaceIndicator extends SchedulerWorkSpace { ): void { const groupedByDate = this.isGroupedByDate(); const repeatCount = groupedByDate ? 1 : groupCount; - Array.from({ length: repeatCount }).forEach((_, i) => { + for (let i = 0; i < repeatCount; i += 1) { const $indicator = this.createIndicator($container); setWidth( @@ -84,7 +84,7 @@ class SchedulerWorkSpaceIndicator extends SchedulerWorkSpace { groupedByDate ? this.getCellWidth() * groupCount : this.getCellWidth(), ); this.groupedStrategy.shiftIndicator($indicator, height, rtlOffset, i); - }); + } } protected createIndicator($container: dxElementWrapper): dxElementWrapper { From 7ee9bb4ae41d24bcc02a7e96d141d18b6a099ce7 Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Wed, 3 Jun 2026 16:31:12 +0200 Subject: [PATCH 06/21] fix: copilot review --- .../js/__internal/scheduler/workspaces/m_timeline_month.ts | 2 +- .../js/__internal/scheduler/workspaces/m_work_space.ts | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline_month.ts b/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline_month.ts index da37cfd36648..4dd986dd57a3 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline_month.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline_month.ts @@ -27,7 +27,7 @@ class SchedulerTimelineMonth extends SchedulerTimeline { return TIMELINE_CLASS; } - protected override getDateHeaderTemplate(): template | undefined { + protected override getDateHeaderTemplate(): template | undefined | null { return this.option('dateCellTemplate'); } 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 f9d4e4835560..772640de85a8 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space.ts @@ -1,3 +1,4 @@ +import type { template } from '@js/common'; import { locate, resetPosition } from '@js/common/core/animation/translator'; import { name as clickEventName } from '@js/common/core/events/click'; import { name as contextMenuEventName } from '@js/common/core/events/contextmenu'; @@ -2846,7 +2847,7 @@ class SchedulerWorkSpace extends Widget { this.$element().addClass(className); } - protected getDateHeaderTemplate() { + protected getDateHeaderTemplate(): template | undefined | null { return this.option('dateCellTemplate'); } From dad721d9a84af26074da613d5767ab04afb5e5c5 Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Thu, 4 Jun 2026 12:25:03 +0200 Subject: [PATCH 07/21] refactor: remove unkown type for cellTemplate --- .../scheduler/workspaces/m_agenda.ts | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/devextreme/js/__internal/scheduler/workspaces/m_agenda.ts b/packages/devextreme/js/__internal/scheduler/workspaces/m_agenda.ts index 7b1c068b1ff0..a9da9b742c67 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_agenda.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/m_agenda.ts @@ -3,6 +3,7 @@ import registerComponent from '@js/core/component_registrator'; import domAdapter from '@js/core/dom_adapter'; import { getPublicElement } from '@js/core/element'; import $, { type dxElementWrapper } from '@js/core/renderer'; +import type { TemplateBase } from '@js/core/templates/template_base'; import { noop } from '@js/core/utils/common'; import dateUtils from '@js/core/utils/date'; import { extend } from '@js/core/utils/extend'; @@ -53,7 +54,7 @@ interface AgendaRenderOptions { cellCount?: number; rowClass?: string; cellClass?: string; - cellTemplate?: unknown; + cellTemplate?: TemplateBase; getStartDate?: (rowIndex: number) => Date; } @@ -175,7 +176,7 @@ class SchedulerAgenda extends WorkSpace { } private recalculateAgenda(rows: number[][]): void { - let cellTemplates: unknown[] = []; + let cellTemplates: (() => dxElementWrapper)[] = []; this.cleanView(); if (this.rowsIsEmpty(rows)) { @@ -247,7 +248,10 @@ class SchedulerAgenda extends WorkSpace { return this.$groupTable as dxElementWrapper | null; } - protected override makeGroupRows(): { elements: dxElementWrapper; cellTemplates: unknown[] } { + protected override makeGroupRows(): { + elements: dxElementWrapper; + cellTemplates: (() => dxElementWrapper)[]; + } { const resourceManager = this.option('getResourceManager')(); const allAppointments = (this.option('getFilteredItems') as () => ListEntity[])(); const tree = reduceResourcesTree( @@ -256,11 +260,9 @@ class SchedulerAgenda extends WorkSpace { allAppointments, ); - const cellTemplate = this.option('resourceCellTemplate') as { - render?: (model: unknown) => unknown; - }; + const cellTemplate = this.option('resourceCellTemplate') as TemplateBase | undefined; const getGroupHeaderContentClass = GROUP_HEADER_CONTENT_CLASS; - const cellTemplates: unknown[] = []; + const cellTemplates: (() => dxElementWrapper)[] = []; const table = tableCreator.makeGroupedTableFromJSON(tree, { cellTag: 'th', @@ -394,10 +396,8 @@ class SchedulerAgenda extends WorkSpace { // eslint-disable-next-line @typescript-eslint/no-unused-vars delayCellTemplateRendering?: unknown, ): void { - const cellTemplates: unknown[] = []; - const cellTemplateOpt = options.cellTemplate as { - render?: (templateOptions: unknown) => unknown; - } | undefined; + const cellTemplates: (() => dxElementWrapper)[] = []; + const cellTemplateOpt = options.cellTemplate; this.$rows = []; let i = 0; @@ -466,7 +466,7 @@ class SchedulerAgenda extends WorkSpace { cellCount: 1, rowClass: TIME_PANEL_ROW_CLASS, cellClass: TIME_PANEL_CELL_CLASS, - cellTemplate: this.option('dateCellTemplate'), + cellTemplate: this.option('dateCellTemplate') as TemplateBase | undefined, getStartDate: this.getTimePanelStartDate.bind(this), }); } From 46a2d0f29698782332fd3fa182f9d381f2f54e21 Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Thu, 4 Jun 2026 12:35:59 +0200 Subject: [PATCH 08/21] refactor: remove unknown type from agenda --- .../scheduler/workspaces/m_agenda.ts | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/packages/devextreme/js/__internal/scheduler/workspaces/m_agenda.ts b/packages/devextreme/js/__internal/scheduler/workspaces/m_agenda.ts index a9da9b742c67..558a527275d9 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_agenda.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/m_agenda.ts @@ -12,6 +12,7 @@ import { setHeight, setOuterHeight } from '@js/core/utils/size'; import type { OptionChanged } from '@ts/core/widget/types'; import { EMPTY_ACTIVE_STATE_UNIT } from '@ts/core/widget/widget'; +import type { Rect } from '../appointments/resizing/types'; import { DATE_TABLE_CLASS, DATE_TABLE_ROW_CLASS, @@ -21,6 +22,7 @@ import { } from '../m_classes'; import tableCreatorModule from '../m_table_creator'; import { agendaUtils, formatWeekday, getVerticalGroupCountClass } from '../r1/utils/index'; +import type { ResourceId } from '../utils/loader/types'; import { VIEWS } from '../utils/options/constants_view'; import { reduceResourcesTree } from '../utils/resource_manager/agenda_group_utils'; import type { GroupNode } from '../utils/resource_manager/types'; @@ -369,7 +371,7 @@ class SchedulerAgenda extends WorkSpace { model: { text: string; date: Date | undefined; - groups: Record; + groups: Record; groupIndex: number | undefined; }; container: Element; @@ -394,7 +396,7 @@ class SchedulerAgenda extends WorkSpace { protected renderTableBody( options: AgendaRenderOptions, // eslint-disable-next-line @typescript-eslint/no-unused-vars - delayCellTemplateRendering?: unknown, + delayCellTemplateRendering?: boolean, ): void { const cellTemplates: (() => dxElementWrapper)[] = []; const cellTemplateOpt = options.cellTemplate; @@ -562,12 +564,16 @@ class SchedulerAgenda extends WorkSpace { } getDOMElementsMetaData(): { - dateTableCellsMeta: Record[][]; - allDayPanelCellsMeta: Record[]; + dateTableCellsMeta: Rect[][]; + allDayPanelCellsMeta: Rect[]; } { return { - dateTableCellsMeta: [[{}]], - allDayPanelCellsMeta: [{}], + dateTableCellsMeta: [[{ + top: 0, left: 0, width: 0, height: 0, + }]], + allDayPanelCellsMeta: [{ + top: 0, left: 0, width: 0, height: 0, + }], }; } } From b22d6208d34c36943dc4d7c9173c50f4105225d8 Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Thu, 4 Jun 2026 12:43:40 +0200 Subject: [PATCH 09/21] refactor: remove unknown type from timeline --- .../js/__internal/scheduler/workspaces/m_timeline.ts | 8 ++++++-- .../js/__internal/scheduler/workspaces/m_work_space.ts | 9 ++++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline.ts b/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline.ts index b39d3cab8061..f99f0a86c0ae 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline.ts @@ -10,6 +10,7 @@ import type { dxSchedulerOptions } from '@js/ui/scheduler'; // NOTE: Renovation component import. import { HeaderPanelTimelineComponent } from '@ts/scheduler/r1/components/index'; import { timelineWeekUtils } from '@ts/scheduler/r1/utils/index'; +import type { ResourceLoader } from '@ts/scheduler/utils/loader/resource_loader'; import { GROUP_HEADER_CONTENT_CLASS, @@ -57,7 +58,7 @@ class SchedulerTimeline extends SchedulerWorkSpace { protected override getTotalRowCount( groupCount: number, // eslint-disable-next-line @typescript-eslint/no-unused-vars - includeAllDayPanelRows?: unknown, + includeAllDayPanelRows?: boolean, ): number { if (this.isHorizontalGroupedWorkSpace()) { return this.getRowCount(); @@ -414,7 +415,10 @@ class SchedulerTimeline extends SchedulerWorkSpace { } } - protected override makeGroupRows(groups: unknown[], groupByDate: boolean): unknown { + protected override makeGroupRows(groups: ResourceLoader[], groupByDate: boolean): { + elements: dxElementWrapper | dxElementWrapper[]; + cellTemplates: (() => dxElementWrapper)[]; + } { const tableCreatorStrategy = this.option('groupOrientation') === 'vertical' ? tableCreator.VERTICAL : tableCreator.HORIZONTAL; return tableCreator.makeGroupedTable( 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 772640de85a8..bac264f9bf4c 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space.ts @@ -1179,7 +1179,7 @@ class SchedulerWorkSpace extends Widget { return this.groupedStrategy.getTotalCellCount(groupCount); } - protected getTotalRowCount(groupCount, includeAllDayPanelRows?: any) { + protected getTotalRowCount(groupCount: number, includeAllDayPanelRows?: boolean) { let result = this.groupedStrategy.getTotalRowCount(groupCount); if (includeAllDayPanelRows && this.isAllDayPanelVisible) { @@ -2958,7 +2958,7 @@ class SchedulerWorkSpace extends Widget { protected renderGroupHeader() { const $container = this.getGroupHeaderContainer(); const groupCount = this.getGroupCount(); - let cellTemplates = []; + let cellTemplates: (() => dxElementWrapper)[] = []; if (groupCount) { const groupRows = this.makeGroupRows(this.option('groups'), this.option('groupByDate')); this.attachGroupCountClass(); @@ -2977,7 +2977,10 @@ class SchedulerWorkSpace extends Widget { }); } - protected makeGroupRows(groups, groupByDate): any { + protected makeGroupRows(groups: ResourceLoader[], groupByDate: boolean): { + elements: dxElementWrapper | dxElementWrapper[]; + cellTemplates: (() => dxElementWrapper)[]; + } { const tableCreatorStrategy = this.isVerticalGroupedWorkSpace() ? tableCreator.VERTICAL : tableCreator.HORIZONTAL; return tableCreator.makeGroupedTable( From 3242b0394db951a93cc61c28d9c18cc4e0f0942f Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Thu, 4 Jun 2026 13:02:20 +0200 Subject: [PATCH 10/21] refactor: remove unknown from WorkspaceOptionChangedOptions --- .../scheduler/workspaces/m_work_space.ts | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) 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 bac264f9bf4c..6357f257a5a3 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space.ts @@ -12,6 +12,7 @@ import pointerEvents from '@js/common/core/events/pointer'; import { addNamespace, isMouseEvent } from '@js/common/core/events/utils/index'; import domAdapter from '@js/core/dom_adapter'; import type { OptionChangedEventInfo } from '@js/core/dom_component'; +import type { DxElement } from '@js/core/element'; import { getPublicElement } from '@js/core/element'; import type { dxElementWrapper } from '@js/core/renderer'; import $ from '@js/core/renderer'; @@ -45,6 +46,7 @@ import { TimePanelComponent, } from '@ts/scheduler/r1/components/index'; import type { ViewContext } from '@ts/scheduler/r1/components/types'; +import type { TimeZoneCalculator } from '@ts/scheduler/r1/timezone_calculator/calculator'; import { calculateIsGroupedAllDayPanel, calculateViewStartDate, @@ -75,6 +77,7 @@ 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 { ViewCellData } from '../types'; import type { ResourceLoader } from '../utils/loader/resource_loader'; import type { SafeSchedulerOptions } from '../utils/options/types'; import { @@ -240,18 +243,22 @@ export type WorkspaceOptionsInternal = Omit & { }; export type WorkspaceOptionChangedOptions = WorkspaceOptionsInternal & { - onSelectionChanged?: unknown; - onSelectionEnd?: unknown; - onCellClick?: unknown; - onCellContextMenu?: unknown; + onSelectionChanged?: (args: { selectedCellData: ViewCellData[] }) => void; + onSelectionEnd?: (args: { selectedCellData: ViewCellData[] }) => void; + onCellClick?: (args: { cellData: ViewCellData; cellElement: DxElement; event: Event }) => void; + onCellContextMenu?: (args: { + cellData: ViewCellData; + cellElement: DxElement; + event: Event; + }) => void; viewOffset?: number; groupOrientation?: 'horizontal' | 'vertical'; - timeZoneCalculator?: unknown; + timeZoneCalculator?: TimeZoneCalculator; allDayExpanded?: boolean; width?: number | string; allowMultipleCellSelection?: boolean; - selectedCellData?: unknown; - scrolling?: unknown; + selectedCellData?: ViewCellData[]; + scrolling?: SafeSchedulerOptions['scrolling']; schedulerHeight?: number; schedulerWidth?: number; agendaDuration?: number; From 039b66bc685216c449ea3a38ab20d96d3a21c6ca Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Thu, 4 Jun 2026 13:04:22 +0200 Subject: [PATCH 11/21] refactor: remove unknown from m_work_space --- .../js/__internal/scheduler/workspaces/m_work_space.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 6357f257a5a3..70bfc0967cd7 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space.ts @@ -737,14 +737,14 @@ class SchedulerWorkSpace extends Widget { // To prevent scroll container focus in native mode we set tabindex -1 to container // In simulated mode focusable behavior prevented by useKeyboard: false private option onInitialized: ({ component }) => { - const useKeyboardDisabled = (component?.option('useKeyboard') as unknown as boolean | undefined) === false; - const useNativeEnabled = (component?.option('useNative') as unknown as boolean | undefined) === true; + const useKeyboardDisabled = component?.option().useKeyboard === false; + const useNativeEnabled = component?.option().useNative === true; if (useKeyboardDisabled && useNativeEnabled) { $(component?.container()).attr('tabindex', -1); } }, onOptionChanged: ({ fullName, value, component }) => { - const useKeyboardDisabled = (component.option('useKeyboard') as unknown as boolean | undefined) === false; + const useKeyboardDisabled = component.option().useKeyboard === false; if (useKeyboardDisabled && fullName === 'useNative' && value === true) { $(component.container()).attr('tabindex', -1); } From c7ff51242f86c5d5d68b990b8a7d117f7ae6a615 Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Thu, 4 Jun 2026 13:12:36 +0200 Subject: [PATCH 12/21] fix: copilot review --- .../js/__internal/scheduler/workspaces/m_agenda.ts | 8 +++++--- .../js/__internal/scheduler/workspaces/m_work_space.ts | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/devextreme/js/__internal/scheduler/workspaces/m_agenda.ts b/packages/devextreme/js/__internal/scheduler/workspaces/m_agenda.ts index 558a527275d9..19b45a94709d 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_agenda.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/m_agenda.ts @@ -114,7 +114,9 @@ class SchedulerAgenda extends WorkSpace { } } else if (!this.$groupTable) { this.initGroupTable(); - this.$dateTableScrollable.$content().prepend(this.$groupTable); + if (this.$groupTable) { + this.$dateTableScrollable.$content().prepend(this.$groupTable); + } } super._optionChanged(args); break; @@ -246,8 +248,8 @@ class SchedulerAgenda extends WorkSpace { return rows.filter((row) => row.length && !isEmpty(row)); } - protected override getGroupHeaderContainer(): dxElementWrapper | null { - return this.$groupTable as dxElementWrapper | null; + protected override getGroupHeaderContainer(): dxElementWrapper | null | undefined { + return this.$groupTable; } protected override makeGroupRows(): { 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 70bfc0967cd7..dbaaec8bf1ee 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space.ts @@ -323,7 +323,7 @@ class SchedulerWorkSpace extends Widget { private contextMenuAction: any; - protected $groupTable: any; + protected $groupTable: dxElementWrapper | null | undefined; protected $thead: any; From 34ba005550f192b6a7009bb849b420501f945592 Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Thu, 4 Jun 2026 13:12:56 +0200 Subject: [PATCH 13/21] fix: copilot review --- .../devextreme/js/__internal/scheduler/workspaces/m_agenda.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/devextreme/js/__internal/scheduler/workspaces/m_agenda.ts b/packages/devextreme/js/__internal/scheduler/workspaces/m_agenda.ts index 19b45a94709d..ca366570d42c 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_agenda.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/m_agenda.ts @@ -85,7 +85,6 @@ class SchedulerAgenda extends WorkSpace { _getDefaultOptions(): AgendaDefaultOptions { const defaultOptions = extend(super._getDefaultOptions(), { - // Number | "month" agendaDuration: 7, rowHeight: 60, noDataText: '', From 30e29baee2cc20a92b6b0ad78ce82324cb486162 Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Thu, 4 Jun 2026 13:24:59 +0200 Subject: [PATCH 14/21] fix: fix test --- .../tests/DevExpress.ui.widgets.scheduler/agenda.tests.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/agenda.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/agenda.tests.js index d326f8bdb558..03d11c28917a 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/agenda.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/agenda.tests.js @@ -186,8 +186,12 @@ module('Agenda', {}, () => { assert.deepEqual( instance.getDOMElementsMetaData(), { - dateTableCellsMeta: [[{}]], - allDayPanelCellsMeta: [{}], + dateTableCellsMeta: [[{ + top: 0, left: 0, width: 0, height: 0, + }]], + allDayPanelCellsMeta: [{ + top: 0, left: 0, width: 0, height: 0, + }], }, 'Correct DOM meta data', ); From eef9bdb1cfc78df47e32b2c67fa97be87a5a75ea Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Thu, 4 Jun 2026 14:37:22 +0200 Subject: [PATCH 15/21] refactor: remove WorkspaceDateTableScrollableConfig and WorkspaceHeaderScrollableConfig --- .../scheduler/workspaces/m_timeline.ts | 12 +++---- .../scheduler/workspaces/m_work_space.ts | 36 ++++--------------- 2 files changed, 12 insertions(+), 36 deletions(-) diff --git a/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline.ts b/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline.ts index f99f0a86c0ae..32455ac89b8d 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline.ts @@ -10,7 +10,7 @@ import type { dxSchedulerOptions } from '@js/ui/scheduler'; // NOTE: Renovation component import. import { HeaderPanelTimelineComponent } from '@ts/scheduler/r1/components/index'; import { timelineWeekUtils } from '@ts/scheduler/r1/utils/index'; -import type { ResourceLoader } from '@ts/scheduler/utils/loader/resource_loader'; +import type { ScrollableProperties } from '@ts/ui/scroll_view/scrollable'; import { GROUP_HEADER_CONTENT_CLASS, @@ -19,7 +19,7 @@ import { import tableCreatorModule from '../m_table_creator'; import timezoneUtils from '../m_utils_time_zone'; import HorizontalShader from '../shaders/current_time_shader_horizontal'; -import type { WorkspaceDateTableScrollableConfig, WorkspaceHeaderScrollableConfig } from './m_work_space'; +import type { ResourceLoader } from '../utils/loader/resource_loader'; import SchedulerWorkSpace, { type WorkSpaceIndicatorDefaultOptions } from './m_work_space_indicator'; import type { ViewDataProviderOptions } from './view_model/m_types'; @@ -79,25 +79,25 @@ class SchedulerTimeline extends SchedulerWorkSpace { return getBoundingRect(this.$element().get(0)).height as number; } - protected override dateTableScrollableConfig(): WorkspaceDateTableScrollableConfig { + protected override dateTableScrollableConfig(): ScrollableProperties { const config = super.dateTableScrollableConfig(); const timelineConfig = { direction: HORIZONTAL, }; - return this.option('crossScrollingEnabled') ? config : extend(config, timelineConfig) as WorkspaceDateTableScrollableConfig; + return this.option('crossScrollingEnabled') ? config : extend(config, timelineConfig) as ScrollableProperties; } protected override needCreateCrossScrolling(): boolean { return true; } - protected override headerScrollableConfig(): WorkspaceHeaderScrollableConfig { + protected override headerScrollableConfig(): ScrollableProperties { const config = super.headerScrollableConfig(); return extend(config, { scrollByContent: true, - }) as WorkspaceHeaderScrollableConfig; + }) as ScrollableProperties; } supportAllDayRow(): boolean { 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 dbaaec8bf1ee..0c6416baac46 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space.ts @@ -11,7 +11,6 @@ import { import pointerEvents from '@js/common/core/events/pointer'; import { addNamespace, isMouseEvent } from '@js/common/core/events/utils/index'; import domAdapter from '@js/core/dom_adapter'; -import type { OptionChangedEventInfo } from '@js/core/dom_component'; import type { DxElement } from '@js/core/element'; import { getPublicElement } from '@js/core/element'; import type { dxElementWrapper } from '@js/core/renderer'; @@ -31,7 +30,6 @@ import { } from '@js/core/utils/size'; import { isDefined } from '@js/core/utils/type'; import { getWindow, hasWindow } from '@js/core/utils/window'; -import type { InitializedEventInfo } from '@js/events'; import type { ScrollEvent } from '@js/ui/scroll_view'; import errors from '@js/ui/widget/ui.errors'; import Widget from '@js/ui/widget/ui.widget'; @@ -56,7 +54,7 @@ import { isDateAndTimeView, } from '@ts/scheduler/r1/utils/index'; import type { ViewType } from '@ts/scheduler/types'; -import Scrollable from '@ts/ui/scroll_view/scrollable'; +import Scrollable, { type ScrollableProperties } from '@ts/ui/scroll_view/scrollable'; import type NotifyScheduler from '../base/widget_notify_scheduler'; import { APPOINTMENT_SETTINGS_KEY } from '../constants'; @@ -127,28 +125,6 @@ export interface ViewDateGenerationOptions { viewType: ViewType; } -export interface WorkspaceDateTableScrollableConfig { - useKeyboard: boolean; - bounceEnabled: boolean; - updateManually: boolean; - onScroll: (event: ScrollEvent) => void; - onInitialized: (args: InitializedEventInfo) => void; - onOptionChanged: (args: OptionChangedEventInfo) => void; - direction?: 'horizontal' | 'vertical' | 'both'; - onEnd?: () => void; -} - -export interface WorkspaceHeaderScrollableConfig { - useKeyboard: boolean; - showScrollbar: 'never'; - direction: 'horizontal'; - useNative: false; - updateManually: true; - bounceEnabled: false; - scrollByContent?: boolean; - onScroll: (event: ScrollEvent) => void; -} - const { tableCreator } = tableCreatorModule; // The constant is needed so that the dragging is not sharp. To prevent small twitches @@ -723,8 +699,8 @@ class SchedulerWorkSpace extends Widget { this.$allDayTitle = $('
').appendTo(this.$headerPanelEmptyCell); } - protected dateTableScrollableConfig(): WorkspaceDateTableScrollableConfig { - let config: WorkspaceDateTableScrollableConfig = { + protected dateTableScrollableConfig(): ScrollableProperties { + let config: ScrollableProperties = { useKeyboard: false, bounceEnabled: false, updateManually: true, @@ -773,8 +749,8 @@ class SchedulerWorkSpace extends Widget { } protected createCrossScrollingConfig( - { onScroll }: Pick, - ): Pick { + { onScroll }: Pick, + ): Pick { return { direction: 'both', onScroll: (event: ScrollEvent) => { @@ -797,7 +773,7 @@ class SchedulerWorkSpace extends Widget { }; } - protected headerScrollableConfig(): WorkspaceHeaderScrollableConfig { + protected headerScrollableConfig(): ScrollableProperties { return { useKeyboard: false, showScrollbar: 'never', From 0c2805a1d4ec1a3b8bc6ed292946502c7a1b6c07 Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Thu, 4 Jun 2026 14:38:43 +0200 Subject: [PATCH 16/21] refactor: type getHeaderPanelCellClass --- .../js/__internal/scheduler/workspaces/m_work_space.ts | 2 +- .../__internal/scheduler/workspaces/m_work_space_indicator.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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 0c6416baac46..3eacab6fc46e 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space.ts @@ -2996,7 +2996,7 @@ class SchedulerWorkSpace extends Widget { return {}; } - protected getHeaderPanelCellClass(i) { + protected getHeaderPanelCellClass(i: number): string { const cellClass = `${HEADER_PANEL_CELL_CLASS} ${HORIZONTAL_SIZES_CLASS}`; return this.groupedStrategy.addAdditionalGroupCellClasses(cellClass, i + 1, undefined, undefined, this.isGroupedByDate()); diff --git a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_indicator.ts b/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_indicator.ts index 46b9f0746084..b608a4dd3fe6 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_indicator.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_indicator.ts @@ -201,7 +201,7 @@ class SchedulerWorkSpaceIndicator extends SchedulerWorkSpace { } protected override getHeaderPanelCellClass(i: number): string { - const cellClass = super.getHeaderPanelCellClass(i) as string; + const cellClass = super.getHeaderPanelCellClass(i); if (this.isCurrentTimeHeaderCell(i)) { return `${cellClass} ${HEADER_CURRENT_TIME_CELL_CLASS}`; From f8459c8e0d224445f5bd6de25cba2c0400a503c3 Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Thu, 4 Jun 2026 15:24:05 +0200 Subject: [PATCH 17/21] refactor: rename files in tests --- .../__tests__/workspace.base.test.ts | 12 +++---- .../js/__internal/scheduler/m_scheduler.ts | 14 ++++---- .../__internal/scheduler/m_table_creator.ts | 33 +++++++++++++++---- .../workspaces/{m_agenda.ts => agenda.ts} | 14 ++++---- .../workspaces/m_timeline_work_week.ts | 2 +- .../scheduler/workspaces/m_work_space.ts | 7 ++-- .../workspaces/m_work_space_vertical.ts | 2 +- .../workspaces/m_work_space_work_week.ts | 2 +- .../workspaces/{m_timeline.ts => timeline.ts} | 16 ++++----- .../{m_timeline_day.ts => timeline_day.ts} | 2 +- ...{m_timeline_month.ts => timeline_month.ts} | 2 +- .../{m_timeline_week.ts => timeline_week.ts} | 5 +-- ...{m_work_space_day.ts => work_space_day.ts} | 0 ...e_indicator.ts => work_space_indicator.ts} | 0 ...ork_space_month.ts => work_space_month.ts} | 2 +- ..._work_space_week.ts => work_space_week.ts} | 3 +- 16 files changed, 66 insertions(+), 50 deletions(-) rename packages/devextreme/js/__internal/scheduler/workspaces/{m_agenda.ts => agenda.ts} (97%) rename packages/devextreme/js/__internal/scheduler/workspaces/{m_timeline.ts => timeline.ts} (97%) rename packages/devextreme/js/__internal/scheduler/workspaces/{m_timeline_day.ts => timeline_day.ts} (93%) rename packages/devextreme/js/__internal/scheduler/workspaces/{m_timeline_month.ts => timeline_month.ts} (98%) rename packages/devextreme/js/__internal/scheduler/workspaces/{m_timeline_week.ts => timeline_week.ts} (81%) rename packages/devextreme/js/__internal/scheduler/workspaces/{m_work_space_day.ts => work_space_day.ts} (100%) rename packages/devextreme/js/__internal/scheduler/workspaces/{m_work_space_indicator.ts => work_space_indicator.ts} (100%) rename packages/devextreme/js/__internal/scheduler/workspaces/{m_work_space_month.ts => work_space_month.ts} (98%) rename packages/devextreme/js/__internal/scheduler/workspaces/{m_work_space_week.ts => work_space_week.ts} (89%) diff --git a/packages/devextreme/js/__internal/scheduler/__tests__/workspace.base.test.ts b/packages/devextreme/js/__internal/scheduler/__tests__/workspace.base.test.ts index 17098be9585a..58712491f26f 100644 --- a/packages/devextreme/js/__internal/scheduler/__tests__/workspace.base.test.ts +++ b/packages/devextreme/js/__internal/scheduler/__tests__/workspace.base.test.ts @@ -4,15 +4,15 @@ import { import { logger } from '@ts/core/utils/m_console'; import { getResourceManagerMock } from '../__mock__/resource_manager.mock'; -import SchedulerTimelineDay from '../workspaces/m_timeline_day'; -import SchedulerTimelineMonth from '../workspaces/m_timeline_month'; -import SchedulerTimelineWeek from '../workspaces/m_timeline_week'; import SchedulerTimelineWorkWeek from '../workspaces/m_timeline_work_week'; import type SchedulerWorkSpace from '../workspaces/m_work_space'; -import SchedulerWorkSpaceDay from '../workspaces/m_work_space_day'; -import SchedulerWorkSpaceMonth from '../workspaces/m_work_space_month'; -import SchedulerWorkSpaceWeek from '../workspaces/m_work_space_week'; import SchedulerWorkSpaceWorkWeek from '../workspaces/m_work_space_work_week'; +import SchedulerTimelineDay from '../workspaces/timeline_day'; +import SchedulerTimelineMonth from '../workspaces/timeline_month'; +import SchedulerTimelineWeek from '../workspaces/timeline_week'; +import SchedulerWorkSpaceDay from '../workspaces/work_space_day'; +import SchedulerWorkSpaceMonth from '../workspaces/work_space_month'; +import SchedulerWorkSpaceWeek from '../workspaces/work_space_week'; import { setupSchedulerTestEnvironment } from './__mock__/m_mock_scheduler'; jest.mock('@ts/core/m_devices', () => { diff --git a/packages/devextreme/js/__internal/scheduler/m_scheduler.ts b/packages/devextreme/js/__internal/scheduler/m_scheduler.ts index bb33fca7b71d..522b2b6356ba 100644 --- a/packages/devextreme/js/__internal/scheduler/m_scheduler.ts +++ b/packages/devextreme/js/__internal/scheduler/m_scheduler.ts @@ -86,15 +86,15 @@ 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'; import type { AppointmentViewModelPlain } from './view_model/types'; -import SchedulerAgenda from './workspaces/m_agenda'; -import SchedulerTimelineDay from './workspaces/m_timeline_day'; -import SchedulerTimelineMonth from './workspaces/m_timeline_month'; -import SchedulerTimelineWeek from './workspaces/m_timeline_week'; +import SchedulerAgenda from './workspaces/agenda'; import SchedulerTimelineWorkWeek from './workspaces/m_timeline_work_week'; -import SchedulerWorkSpaceDay from './workspaces/m_work_space_day'; -import SchedulerWorkSpaceMonth from './workspaces/m_work_space_month'; -import SchedulerWorkSpaceWeek from './workspaces/m_work_space_week'; import SchedulerWorkSpaceWorkWeek from './workspaces/m_work_space_work_week'; +import SchedulerTimelineDay from './workspaces/timeline_day'; +import SchedulerTimelineMonth from './workspaces/timeline_month'; +import SchedulerTimelineWeek from './workspaces/timeline_week'; +import SchedulerWorkSpaceDay from './workspaces/work_space_day'; +import SchedulerWorkSpaceMonth from './workspaces/work_space_month'; +import SchedulerWorkSpaceWeek from './workspaces/work_space_week'; const toMs = dateUtils.dateToMilliseconds; diff --git a/packages/devextreme/js/__internal/scheduler/m_table_creator.ts b/packages/devextreme/js/__internal/scheduler/m_table_creator.ts index 766e45e5bee2..105ea92fbd77 100644 --- a/packages/devextreme/js/__internal/scheduler/m_table_creator.ts +++ b/packages/devextreme/js/__internal/scheduler/m_table_creator.ts @@ -1,13 +1,28 @@ +import type { Orientation, template } from '@js/common'; import domAdapter from '@js/core/dom_adapter'; import { getPublicElement } from '@js/core/element'; import { data as elementData } from '@js/core/element_data'; +import type { dxElementWrapper } from '@js/core/renderer'; import $ from '@js/core/renderer'; import { isFunction } from '@js/core/utils/type'; +import type { ResourceLoader } from './utils/loader/resource_loader'; import type { GroupNode } from './utils/resource_manager/types'; const ROW_SELECTOR = 'tr'; +export interface GroupCssClasses { + groupHeaderRowClass?: string; + groupRowClass?: string; + groupHeaderClass: string | ((index: number) => string); + groupHeaderContentClass?: string; +} + +export interface GroupRows { + elements: dxElementWrapper | dxElementWrapper[]; + cellTemplates: (() => dxElementWrapper)[]; +} + class SchedulerTableCreator { readonly VERTICAL = 'vertical'; @@ -129,16 +144,20 @@ class SchedulerTableCreator { return templateCallbacks; } - makeGroupedTable(type, groups, cssClasses, cellCount, cellTemplate, rowCount, groupByDate) { - let rows: any = []; - + makeGroupedTable( + type: Orientation, + groups: ResourceLoader[], + cssClasses: GroupCssClasses, + cellCount: number, + cellTemplate: template | null | undefined, + rowCount: number, + groupByDate: boolean, + ): GroupRows { if (type === this.VERTICAL) { - rows = this.makeVerticalGroupedRows(groups, cssClasses, cellTemplate, rowCount); - } else { - rows = this.makeHorizontalGroupedRows(groups, cssClasses, cellCount, cellTemplate, groupByDate); + return this.makeVerticalGroupedRows(groups, cssClasses, cellTemplate, rowCount); } - return rows; + return this.makeHorizontalGroupedRows(groups, cssClasses, cellCount, cellTemplate, groupByDate); } makeGroupedTableFromJSON(tree: GroupNode[], config?) { diff --git a/packages/devextreme/js/__internal/scheduler/workspaces/m_agenda.ts b/packages/devextreme/js/__internal/scheduler/workspaces/agenda.ts similarity index 97% rename from packages/devextreme/js/__internal/scheduler/workspaces/m_agenda.ts rename to packages/devextreme/js/__internal/scheduler/workspaces/agenda.ts index ca366570d42c..a75d55e1a105 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_agenda.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/agenda.ts @@ -11,6 +11,7 @@ import { each } from '@js/core/utils/iterator'; import { setHeight, setOuterHeight } from '@js/core/utils/size'; import type { OptionChanged } from '@ts/core/widget/types'; import { EMPTY_ACTIVE_STATE_UNIT } from '@ts/core/widget/widget'; +import type { ScrollableProperties } from '@ts/ui/scroll_view/scrollable'; import type { Rect } from '../appointments/resizing/types'; import { @@ -20,7 +21,7 @@ import { GROUP_ROW_CLASS, TIME_PANEL_CLASS, } from '../m_classes'; -import tableCreatorModule from '../m_table_creator'; +import tableCreatorModule, { type GroupRows } from '../m_table_creator'; import { agendaUtils, formatWeekday, getVerticalGroupCountClass } from '../r1/utils/index'; import type { ResourceId } from '../utils/loader/types'; import { VIEWS } from '../utils/options/constants_view'; @@ -174,7 +175,7 @@ class SchedulerAgenda extends WorkSpace { } protected override renderView(): void { - this.startViewDate = agendaUtils.calculateStartViewDate(this.option('currentDate') as any, this.option('startDayHour') as any); + this.startViewDate = agendaUtils.calculateStartViewDate(this.option('currentDate'), this.option('startDayHour')); this.rows = []; } @@ -210,7 +211,7 @@ class SchedulerAgenda extends WorkSpace { protected override toggleHorizontalScrollClass(): void { return noop(); } - protected override createCrossScrollingConfig(): Pick { + protected override createCrossScrollingConfig(): Pick { return { onScroll: noop, onEnd: noop, @@ -251,10 +252,7 @@ class SchedulerAgenda extends WorkSpace { return this.$groupTable; } - protected override makeGroupRows(): { - elements: dxElementWrapper; - cellTemplates: (() => dxElementWrapper)[]; - } { + protected override makeGroupRows(): GroupRows { const resourceManager = this.option('getResourceManager')(); const allAppointments = (this.option('getFilteredItems') as () => ListEntity[])(); const tree = reduceResourcesTree( @@ -475,7 +473,7 @@ class SchedulerAgenda extends WorkSpace { } private getTimePanelStartDate(rowIndex: number): Date { - const current = new Date(this.option('currentDate') as any); + const current = new Date(this.option('currentDate')); const cellDate = new Date(current.setDate(current.getDate() + rowIndex)); return cellDate; diff --git a/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline_work_week.ts b/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline_work_week.ts index f4fe25697191..c1823c52e86b 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline_work_week.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline_work_week.ts @@ -4,7 +4,7 @@ import { } from '@ts/scheduler/r1/utils/index'; import { VIEWS } from '../utils/options/constants_view'; -import SchedulerTimelineWeek from './m_timeline_week'; +import SchedulerTimelineWeek from './timeline_week'; const TIMELINE_CLASS = 'dx-scheduler-timeline-work-week'; const LAST_DAY_WEEK_INDEX = 5; 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 3eacab6fc46e..267913858559 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space.ts @@ -72,7 +72,7 @@ import { } from '../m_classes'; import { CompactAppointmentsHelper } from '../m_compact_appointments_helper'; import type { SubscribeKey, SubscribeMethods } from '../m_subscribes'; -import tableCreatorModule from '../m_table_creator'; +import tableCreatorModule, { type GroupRows } from '../m_table_creator'; import { utils } from '../m_utils'; import VerticalShader from '../shaders/current_time_shader_vertical'; import type { ViewCellData } from '../types'; @@ -2960,10 +2960,7 @@ class SchedulerWorkSpace extends Widget { }); } - protected makeGroupRows(groups: ResourceLoader[], groupByDate: boolean): { - elements: dxElementWrapper | dxElementWrapper[]; - cellTemplates: (() => dxElementWrapper)[]; - } { + protected makeGroupRows(groups: ResourceLoader[], groupByDate: boolean): GroupRows { const tableCreatorStrategy = this.isVerticalGroupedWorkSpace() ? tableCreator.VERTICAL : tableCreator.HORIZONTAL; return tableCreator.makeGroupedTable( diff --git a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_vertical.ts b/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_vertical.ts index 428b6e95d240..efc3e7a20fc5 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_vertical.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_vertical.ts @@ -1,6 +1,6 @@ import { formatWeekdayAndDay } from '@ts/scheduler/r1/utils/index'; -import SchedulerWorkSpaceIndicator from './m_work_space_indicator'; +import SchedulerWorkSpaceIndicator from './work_space_indicator'; class SchedulerWorkspaceVertical extends SchedulerWorkSpaceIndicator { protected override getFormat() { diff --git a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_work_week.ts b/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_work_week.ts index c0b43a1bc5aa..10acbf950afe 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_work_week.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_work_week.ts @@ -4,7 +4,7 @@ import { } from '@ts/scheduler/r1/utils/index'; import { VIEWS } from '../utils/options/constants_view'; -import SchedulerWorkSpaceWeek from './m_work_space_week'; +import SchedulerWorkSpaceWeek from './work_space_week'; const WORK_WEEK_CLASS = 'dx-scheduler-work-space-work-week'; class SchedulerWorkSpaceWorkWeek extends SchedulerWorkSpaceWeek { diff --git a/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline.ts b/packages/devextreme/js/__internal/scheduler/workspaces/timeline.ts similarity index 97% rename from packages/devextreme/js/__internal/scheduler/workspaces/m_timeline.ts rename to packages/devextreme/js/__internal/scheduler/workspaces/timeline.ts index 32455ac89b8d..40ace86ccdbe 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/timeline.ts @@ -16,12 +16,12 @@ import { GROUP_HEADER_CONTENT_CLASS, GROUP_ROW_CLASS, } from '../m_classes'; -import tableCreatorModule from '../m_table_creator'; +import tableCreatorModule, { type GroupRows } from '../m_table_creator'; import timezoneUtils from '../m_utils_time_zone'; import HorizontalShader from '../shaders/current_time_shader_horizontal'; import type { ResourceLoader } from '../utils/loader/resource_loader'; -import SchedulerWorkSpace, { type WorkSpaceIndicatorDefaultOptions } from './m_work_space_indicator'; import type { ViewDataProviderOptions } from './view_model/m_types'; +import SchedulerWorkSpace, { type WorkSpaceIndicatorDefaultOptions } from './work_space_indicator'; const { tableCreator } = tableCreatorModule; @@ -119,7 +119,7 @@ class SchedulerTimeline extends SchedulerWorkSpace { return false; } - protected incrementDate(date) { + protected incrementDate(date: Date): void { date.setDate(date.getDate() + 1); } @@ -271,7 +271,7 @@ class SchedulerTimeline extends SchedulerWorkSpace { } // eslint-disable-next-line @typescript-eslint/no-unused-vars - protected override getWeekendsCount(argument?: any) { + protected override getWeekendsCount(days: number): number { return 0; } @@ -415,10 +415,10 @@ class SchedulerTimeline extends SchedulerWorkSpace { } } - protected override makeGroupRows(groups: ResourceLoader[], groupByDate: boolean): { - elements: dxElementWrapper | dxElementWrapper[]; - cellTemplates: (() => dxElementWrapper)[]; - } { + protected override makeGroupRows( + groups: ResourceLoader[], + groupByDate: boolean, + ): GroupRows { const tableCreatorStrategy = this.option('groupOrientation') === 'vertical' ? tableCreator.VERTICAL : tableCreator.HORIZONTAL; return tableCreator.makeGroupedTable( diff --git a/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline_day.ts b/packages/devextreme/js/__internal/scheduler/workspaces/timeline_day.ts similarity index 93% rename from packages/devextreme/js/__internal/scheduler/workspaces/m_timeline_day.ts rename to packages/devextreme/js/__internal/scheduler/workspaces/timeline_day.ts index 1d905c9b4db8..96bedf714a6e 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline_day.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/timeline_day.ts @@ -1,7 +1,7 @@ import registerComponent from '@js/core/component_registrator'; import { VIEWS } from '../utils/options/constants_view'; -import SchedulerTimeline from './m_timeline'; +import SchedulerTimeline from './timeline'; const TIMELINE_CLASS = 'dx-scheduler-timeline-day'; diff --git a/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline_month.ts b/packages/devextreme/js/__internal/scheduler/workspaces/timeline_month.ts similarity index 98% rename from packages/devextreme/js/__internal/scheduler/workspaces/m_timeline_month.ts rename to packages/devextreme/js/__internal/scheduler/workspaces/timeline_month.ts index 4dd986dd57a3..e023106ceebb 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline_month.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/timeline_month.ts @@ -5,7 +5,7 @@ import { HeaderPanelComponent } from '@ts/scheduler/r1/components/index'; import { formatWeekdayAndDay, monthUtils } from '@ts/scheduler/r1/utils/index'; import { VIEWS } from '../utils/options/constants_view'; -import SchedulerTimeline from './m_timeline'; +import SchedulerTimeline from './timeline'; import type { ViewDataProviderOptions } from './view_model/m_types'; const TIMELINE_CLASS = 'dx-scheduler-timeline-month'; diff --git a/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline_week.ts b/packages/devextreme/js/__internal/scheduler/workspaces/timeline_week.ts similarity index 81% rename from packages/devextreme/js/__internal/scheduler/workspaces/m_timeline_week.ts rename to packages/devextreme/js/__internal/scheduler/workspaces/timeline_week.ts index ecf3ff4fc537..dd2df1b419aa 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_timeline_week.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/timeline_week.ts @@ -1,12 +1,13 @@ import registerComponent from '@js/core/component_registrator'; +import type { ViewType } from '@js/ui/scheduler'; import { VIEWS } from '../utils/options/constants_view'; -import SchedulerTimeline from './m_timeline'; +import SchedulerTimeline from './timeline'; const TIMELINE_CLASS = 'dx-scheduler-timeline-week'; export default class SchedulerTimelineWeek extends SchedulerTimeline { - get type() { return VIEWS.TIMELINE_WEEK; } + get type(): ViewType { return VIEWS.TIMELINE_WEEK; } protected override getElementClass(): string { return TIMELINE_CLASS; diff --git a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_day.ts b/packages/devextreme/js/__internal/scheduler/workspaces/work_space_day.ts similarity index 100% rename from packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_day.ts rename to packages/devextreme/js/__internal/scheduler/workspaces/work_space_day.ts diff --git a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_indicator.ts b/packages/devextreme/js/__internal/scheduler/workspaces/work_space_indicator.ts similarity index 100% rename from packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_indicator.ts rename to packages/devextreme/js/__internal/scheduler/workspaces/work_space_indicator.ts diff --git a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_month.ts b/packages/devextreme/js/__internal/scheduler/workspaces/work_space_month.ts similarity index 98% rename from packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_month.ts rename to packages/devextreme/js/__internal/scheduler/workspaces/work_space_month.ts index 3f48e543ac2e..b0b81f198bb8 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_month.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/work_space_month.ts @@ -9,7 +9,7 @@ import { formatWeekday, monthUtils } from '@ts/scheduler/r1/utils/index'; import { utils } from '../m_utils'; import { VIEWS } from '../utils/options/constants_view'; import type { ViewDateGenerationOptions } from './m_work_space'; -import SchedulerWorkSpace from './m_work_space_indicator'; +import SchedulerWorkSpace from './work_space_indicator'; const MONTH_CLASS = 'dx-scheduler-work-space-month'; diff --git a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_week.ts b/packages/devextreme/js/__internal/scheduler/workspaces/work_space_week.ts similarity index 89% rename from packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_week.ts rename to packages/devextreme/js/__internal/scheduler/workspaces/work_space_week.ts index 3e825a8ce712..c9ab5838b778 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space_week.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/work_space_week.ts @@ -1,4 +1,5 @@ import registerComponent from '@js/core/component_registrator'; +import type { ViewType } from '@js/ui/scheduler'; import { weekUtils } from '@ts/scheduler/r1/utils/index'; import { VIEWS } from '../utils/options/constants_view'; @@ -6,7 +7,7 @@ import SchedulerWorkSpaceVertical from './m_work_space_vertical'; const WEEK_CLASS = 'dx-scheduler-work-space-week'; class SchedulerWorkSpaceWeek extends SchedulerWorkSpaceVertical { - get type() { return VIEWS.WEEK; } + get type(): ViewType { return VIEWS.WEEK; } protected override getElementClass(): string { return WEEK_CLASS; From 1ca790512ba548ad7a7211d312477b1f3af23134 Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Thu, 4 Jun 2026 15:25:41 +0200 Subject: [PATCH 18/21] refactor: rename files in tests --- .../DevExpress.ui.widgets.scheduler/agenda.tests.js | 2 +- .../appointments.tests.js | 2 +- .../common.options.tests.js | 2 +- .../currentTimeIndicator.tests.js | 10 +++++----- .../timeline.markup.tests.js | 8 ++++---- .../timeline.tests.js | 8 ++++---- .../workSpace.api.tests.js | 4 ++-- .../workSpace.base.tests.js | 12 ++++++------ .../workSpace.day.tests.js | 2 +- .../workSpace.month.tests.js | 2 +- .../workSpace.renovation.tests.js | 12 ++++++------ .../workSpace.viewOffset.tests.js | 10 +++++----- .../workSpace.week.tests.js | 2 +- 13 files changed, 38 insertions(+), 38 deletions(-) diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/agenda.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/agenda.tests.js index 03d11c28917a..c797bb82269a 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/agenda.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/agenda.tests.js @@ -1,5 +1,5 @@ import $ from 'jquery'; -import SchedulerAgenda from '__internal/scheduler/workspaces/m_agenda'; +import SchedulerAgenda from '__internal/scheduler/workspaces/agenda'; import dateLocalization from 'common/core/localization/date'; import { getEmptyResourceManager } from '../../helpers/scheduler/mockResourceManager.js'; diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/appointments.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/appointments.tests.js index b8b92505bdcb..f53b5fb8b4e2 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/appointments.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/appointments.tests.js @@ -6,7 +6,7 @@ import { mockDataAccessor } from '../../helpers/scheduler/mockDataAccessor.js'; import { getEmptyResourceManager } from '../../helpers/scheduler/mockResourceManager.js'; import $ from 'jquery'; -import '__internal/scheduler/workspaces/m_work_space_week'; +import '__internal/scheduler/workspaces/work_space_week'; import SchedulerAppointments from '__internal/scheduler/appointments/m_appointment_collection'; import dblclickEvent from 'common/core/events/dblclick'; import translator from 'common/core/animation/translator'; diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/common.options.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/common.options.tests.js index 575f8438f9cd..a69ec3fa47e1 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/common.options.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/common.options.tests.js @@ -7,7 +7,7 @@ import 'fluent_blue_light.css!'; import { triggerHidingEvent, triggerShownEvent } from 'common/core/events/visibility_change'; import $ from 'jquery'; -import dxSchedulerWorkSpaceDay from '__internal/scheduler/workspaces/m_work_space_day'; +import dxSchedulerWorkSpaceDay from '__internal/scheduler/workspaces/work_space_day'; import keyboardMock from '../../helpers/keyboardMock.js'; import pointerMock from '../../helpers/pointerMock.js'; import { createWrapper, initTestMarkup } from '../../helpers/scheduler/helpers.js'; diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/currentTimeIndicator.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/currentTimeIndicator.tests.js index 763d750cb6b8..ab3898d17b81 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/currentTimeIndicator.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/currentTimeIndicator.tests.js @@ -17,12 +17,12 @@ const SCHEDULER_DATE_TIME_INDICATOR_CLASS = 'dx-scheduler-date-time-indicator'; import 'fluent_blue_light.css!'; -import '__internal/scheduler/workspaces/m_work_space_day'; -import '__internal/scheduler/workspaces/m_work_space_week'; -import '__internal/scheduler/workspaces/m_timeline_day'; -import '__internal/scheduler/workspaces/m_timeline_week'; +import '__internal/scheduler/workspaces/work_space_day'; +import '__internal/scheduler/workspaces/work_space_week'; +import '__internal/scheduler/workspaces/timeline_day'; +import '__internal/scheduler/workspaces/timeline_week'; import '__internal/scheduler/workspaces/m_timeline_work_week'; -import '__internal/scheduler/workspaces/m_timeline_month'; +import '__internal/scheduler/workspaces/timeline_month'; QUnit.testStart(function() { $('#qunit-fixture').html('
'); diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/timeline.markup.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/timeline.markup.tests.js index f433207e67af..e7ccdee90aba 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/timeline.markup.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/timeline.markup.tests.js @@ -1,9 +1,9 @@ import $ from 'jquery'; -import SchedulerTimeline from '__internal/scheduler/workspaces/m_timeline'; -import SchedulerTimelineDay from '__internal/scheduler/workspaces/m_timeline_day'; -import SchedulerTimelineWeek from '__internal/scheduler/workspaces/m_timeline_week'; +import SchedulerTimeline from '__internal/scheduler/workspaces/timeline'; +import SchedulerTimelineDay from '__internal/scheduler/workspaces/timeline_day'; +import SchedulerTimelineWeek from '__internal/scheduler/workspaces/timeline_week'; import SchedulerTimelineWorkWeek from '__internal/scheduler/workspaces/m_timeline_work_week'; -import SchedulerTimelineMonth from '__internal/scheduler/workspaces/m_timeline_month'; +import SchedulerTimelineMonth from '__internal/scheduler/workspaces/timeline_month'; import dateLocalization from 'common/core/localization/date'; import SchedulerWorkSpaceVerticalStrategy from '__internal/scheduler/workspaces/m_work_space_grouped_strategy_vertical'; import SchedulerWorkSpaceHorizontalStrategy from '__internal/scheduler/workspaces/m_work_space_grouped_strategy_horizontal'; diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/timeline.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/timeline.tests.js index 5d9d239a9e94..28f270f21621 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/timeline.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/timeline.tests.js @@ -4,10 +4,10 @@ import resizeCallbacks from 'core/utils/resize_callbacks'; import { triggerHidingEvent, triggerShownEvent } from 'common/core/events/visibility_change'; import 'fluent_blue_light.css!'; import $ from 'jquery'; -import '__internal/scheduler/workspaces/m_timeline'; -import '__internal/scheduler/workspaces/m_timeline_day'; -import '__internal/scheduler/workspaces/m_timeline_month'; -import '__internal/scheduler/workspaces/m_timeline_week'; +import '__internal/scheduler/workspaces/timeline'; +import '__internal/scheduler/workspaces/timeline_day'; +import '__internal/scheduler/workspaces/timeline_month'; +import '__internal/scheduler/workspaces/timeline_week'; import '__internal/scheduler/workspaces/m_timeline_work_week'; import keyboardMock from '../../helpers/keyboardMock.js'; import pointerMock from '../../helpers/pointerMock.js'; diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/workSpace.api.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/workSpace.api.tests.js index 98202db67e19..e989cec079e4 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/workSpace.api.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/workSpace.api.tests.js @@ -1,8 +1,8 @@ import 'fluent_blue_light.css!'; import $ from 'jquery'; -import '__internal/scheduler/workspaces/m_work_space_month'; -import '__internal/scheduler/workspaces/m_work_space_week'; +import '__internal/scheduler/workspaces/work_space_month'; +import '__internal/scheduler/workspaces/work_space_week'; import { applyWorkspaceGroups, diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/workSpace.base.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/workSpace.base.tests.js index adf684903370..f7196289aba7 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/workSpace.base.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/workSpace.base.tests.js @@ -4,12 +4,12 @@ import 'fluent_blue_light.css!'; import $ from 'jquery'; import dateLocalization from 'common/core/localization/date'; -import '__internal/scheduler/workspaces/m_work_space_day'; -import '__internal/scheduler/workspaces/m_work_space_week'; -import '__internal/scheduler/workspaces/m_work_space_month'; -import '__internal/scheduler/workspaces/m_timeline_day'; -import '__internal/scheduler/workspaces/m_timeline_week'; -import '__internal/scheduler/workspaces/m_timeline_month'; +import '__internal/scheduler/workspaces/work_space_day'; +import '__internal/scheduler/workspaces/work_space_week'; +import '__internal/scheduler/workspaces/work_space_month'; +import '__internal/scheduler/workspaces/timeline_day'; +import '__internal/scheduler/workspaces/timeline_week'; +import '__internal/scheduler/workspaces/timeline_month'; import { getEmptyResourceManager } from '../../helpers/scheduler/mockResourceManager.js'; diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/workSpace.day.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/workSpace.day.tests.js index ff8b429828d3..1cafe7833db2 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/workSpace.day.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/workSpace.day.tests.js @@ -4,7 +4,7 @@ import $ from 'jquery'; import resizeCallbacks from 'core/utils/resize_callbacks'; import dateLocalization from 'common/core/localization/date'; -import '__internal/scheduler/workspaces/m_work_space_day'; +import '__internal/scheduler/workspaces/work_space_day'; import { applyWorkspaceGroups, diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/workSpace.month.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/workSpace.month.tests.js index 8b30fd37d9a2..70f6af424931 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/workSpace.month.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/workSpace.month.tests.js @@ -3,7 +3,7 @@ import resizeCallbacks from 'core/utils/resize_callbacks'; import 'fluent_blue_light.css!'; import $ from 'jquery'; -import '__internal/scheduler/workspaces/m_work_space_month'; +import '__internal/scheduler/workspaces/work_space_month'; import { getGroupWidth } from '__internal/scheduler/workspaces/helpers/m_position_helper'; import { getEmptyResourceManager, getWorkspaceResourceConfig } from '../../helpers/scheduler/mockResourceManager.js'; diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/workSpace.renovation.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/workSpace.renovation.tests.js index 551cc2999625..1bb8cb716820 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/workSpace.renovation.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/workSpace.renovation.tests.js @@ -5,13 +5,13 @@ import $ from 'jquery'; import { supportedScrollingModes } from '../../helpers/scheduler/helpers.js'; -import '__internal/scheduler/workspaces/m_work_space_day'; -import '__internal/scheduler/workspaces/m_work_space_month'; -import '__internal/scheduler/workspaces/m_work_space_week'; +import '__internal/scheduler/workspaces/work_space_day'; +import '__internal/scheduler/workspaces/work_space_month'; +import '__internal/scheduler/workspaces/work_space_week'; -import '__internal/scheduler/workspaces/m_timeline_day'; -import '__internal/scheduler/workspaces/m_timeline_month'; -import '__internal/scheduler/workspaces/m_timeline_week'; +import '__internal/scheduler/workspaces/timeline_day'; +import '__internal/scheduler/workspaces/timeline_month'; +import '__internal/scheduler/workspaces/timeline_week'; import keyboardMock from '../../helpers/keyboardMock.js'; import { applyWorkspaceGroups, getEmptyResourceManager } from '../../helpers/scheduler/mockResourceManager.js'; diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/workSpace.viewOffset.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/workSpace.viewOffset.tests.js index b51e7d6b42bc..ecc6fe4c8302 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/workSpace.viewOffset.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/workSpace.viewOffset.tests.js @@ -1,11 +1,11 @@ import $ from 'jquery'; // workspace imports -import '__internal/scheduler/workspaces/m_work_space_day'; -import '__internal/scheduler/workspaces/m_work_space_week'; -import '__internal/scheduler/workspaces/m_work_space_month'; -import '__internal/scheduler/workspaces/m_timeline_day'; -import '__internal/scheduler/workspaces/m_timeline_month'; +import '__internal/scheduler/workspaces/work_space_day'; +import '__internal/scheduler/workspaces/work_space_week'; +import '__internal/scheduler/workspaces/work_space_month'; +import '__internal/scheduler/workspaces/timeline_day'; +import '__internal/scheduler/workspaces/timeline_month'; import { getEmptyResourceManager } from '../../helpers/scheduler/mockResourceManager.js'; diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/workSpace.week.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/workSpace.week.tests.js index 00caa5eb920f..245e8439740d 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/workSpace.week.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/workSpace.week.tests.js @@ -3,7 +3,7 @@ import { triggerShownEvent } from 'common/core/events/visibility_change'; import 'fluent_blue_light.css!'; import $ from 'jquery'; -import '__internal/scheduler/workspaces/m_work_space_week'; +import '__internal/scheduler/workspaces/work_space_week'; import '__internal/scheduler/workspaces/m_work_space_work_week'; import { From bd31df2a5e81f812f1214c434fe6697fead9c76c Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Thu, 4 Jun 2026 17:50:51 +0200 Subject: [PATCH 19/21] refactor: supprest type errors for compatibility --- .../js/__internal/scheduler/workspaces/timeline_month.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/devextreme/js/__internal/scheduler/workspaces/timeline_month.ts b/packages/devextreme/js/__internal/scheduler/workspaces/timeline_month.ts index e023106ceebb..1c088ed3626f 100644 --- a/packages/devextreme/js/__internal/scheduler/workspaces/timeline_month.ts +++ b/packages/devextreme/js/__internal/scheduler/workspaces/timeline_month.ts @@ -27,6 +27,7 @@ class SchedulerTimelineMonth extends SchedulerTimeline { return TIMELINE_CLASS; } + // @ts-expect-error protected override getDateHeaderTemplate(): template | undefined | null { return this.option('dateCellTemplate'); } @@ -39,6 +40,7 @@ class SchedulerTimelineMonth extends SchedulerTimeline { return true; } + // @ts-expect-error protected override getFormat(): (date: Date) => string { return formatWeekdayAndDay; } From 11d6a024a43c7d6483e8fb6cd58d87b7a4930bb2 Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Thu, 4 Jun 2026 18:02:53 +0200 Subject: [PATCH 20/21] fix: fix test loading --- .../workSpace.navigation.tests.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/workSpace.navigation.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/workSpace.navigation.tests.js index f4475aca92ef..e1be68ccc78c 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/workSpace.navigation.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/workSpace.navigation.tests.js @@ -3,9 +3,9 @@ import { noop } from 'core/utils/common'; import { isRenderer } from 'core/utils/type'; import $ from 'jquery'; -import '__internal/scheduler/workspaces/m_work_space_day'; -import '__internal/scheduler/workspaces/m_work_space_month'; -import '__internal/scheduler/workspaces/m_work_space_work_week'; +import '__internal/scheduler/workspaces/work_space_day'; +import '__internal/scheduler/workspaces/work_space_month'; +import '__internal/scheduler/workspaces/work_space_work_week'; import keyboardMock from '../../helpers/keyboardMock.js'; import memoryLeaksHelper from '../../helpers/memoryLeaksHelper.js'; From fe1bee4b662d47a83204e635bfd15aef601952b8 Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Thu, 4 Jun 2026 18:03:16 +0200 Subject: [PATCH 21/21] fix: fix test loading --- .../workSpace.navigation.tests.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/workSpace.navigation.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/workSpace.navigation.tests.js index e1be68ccc78c..bff1349dd1e8 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/workSpace.navigation.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets.scheduler/workSpace.navigation.tests.js @@ -5,7 +5,7 @@ import $ from 'jquery'; import '__internal/scheduler/workspaces/work_space_day'; import '__internal/scheduler/workspaces/work_space_month'; -import '__internal/scheduler/workspaces/work_space_work_week'; +import '__internal/scheduler/workspaces/m_work_space_work_week'; import keyboardMock from '../../helpers/keyboardMock.js'; import memoryLeaksHelper from '../../helpers/memoryLeaksHelper.js';