Skip to content

Commit

Permalink
Scheduler(T1202735 + T1205763 + ⁠⁠T1205768 + T1205772): Fix current t…
Browse files Browse the repository at this point in the history
…ime indicator related issues (DevExpress#26197)

Co-authored-by: Ilya Vinogradov <[email protected]>
  • Loading branch information
williamvinogradov and Ilya Vinogradov committed Dec 15, 2023
1 parent f9a0a15 commit 2858871
Show file tree
Hide file tree
Showing 35 changed files with 447 additions and 102 deletions.
2 changes: 1 addition & 1 deletion js/__internal/scheduler/m_scheduler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1646,7 +1646,7 @@ class Scheduler extends Widget<any> {
this._workSpaceRecalculation = new Deferred();
this._waitAsyncTemplate(() => {
triggerResizeEvent(this._workSpace.$element());
this._workSpace._refreshDateTimeIndication();
this._workSpace.renderCurrentDateTimeLineAndShader();
});
}

Expand Down
33 changes: 18 additions & 15 deletions js/__internal/scheduler/workspaces/m_timeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -369,21 +369,6 @@ class SchedulerTimeline extends SchedulerWorkSpace {

_setHorizontalGroupHeaderCellsHeight() { return noop(); }

_setCurrentTimeCells() {
const timePanelCells = this._getTimePanelCells();
const currentTimeCellIndices = this._getCurrentTimePanelCellIndices();
currentTimeCellIndices.forEach((timePanelCellIndex) => {
timePanelCells.eq(timePanelCellIndex)
.addClass(HEADER_CURRENT_TIME_CELL_CLASS);
});
}

_cleanCurrentTimeCells() {
(this.$element() as any)
.find(`.${HEADER_CURRENT_TIME_CELL_CLASS}`)
.removeClass(HEADER_CURRENT_TIME_CELL_CLASS);
}

_getTimePanelCells() {
return (this.$element() as any)
.find(`.${HEADER_PANEL_CELL_CLASS}:not(.${HEADER_PANEL_WEEK_CELL_CLASS})`);
Expand Down Expand Up @@ -514,6 +499,24 @@ class SchedulerTimeline extends SchedulerWorkSpace {
groupByDate,
);
}

// Old render methods.
// TODO Old render: delete these methods with the old render.

_setCurrentTimeCells(): void {
const timePanelCells = this._getTimePanelCells();
const currentTimeCellIndices = this._getCurrentTimePanelCellIndices();
currentTimeCellIndices.forEach((timePanelCellIndex) => {
timePanelCells.eq(timePanelCellIndex)
.addClass(HEADER_CURRENT_TIME_CELL_CLASS);
});
}

_cleanCurrentTimeCells(): void {
(this.$element() as any)
.find(`.${HEADER_CURRENT_TIME_CELL_CLASS}`)
.removeClass(HEADER_CURRENT_TIME_CELL_CLASS);
}
}

registerComponent('dxSchedulerTimeline', SchedulerTimeline as any);
Expand Down
72 changes: 56 additions & 16 deletions js/__internal/scheduler/workspaces/m_work_space.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,18 @@ import HorizontalGroupedStrategy from './m_work_space_grouped_strategy_horizonta
import VerticalGroupedStrategy from './m_work_space_grouped_strategy_vertical';
import ViewDataProvider from './view_model/m_view_data_provider';

interface RenderComponentOptions {
header?: boolean;
timePanel?: boolean;
dateTable?: boolean;
allDayPanel?: boolean;
}

interface RenderRWorkspaceOptions {
renderComponents: RenderComponentOptions;
generateNewData: boolean;
}

const { tableCreator } = tableCreatorModule;

// TODO: The constant is needed so that the dragging is not sharp. To prevent small twitches
Expand Down Expand Up @@ -166,6 +178,16 @@ const CELL_SELECTOR = `.${DATE_TABLE_CELL_CLASS}, .${ALL_DAY_TABLE_CELL_CLASS}`;

const CELL_INDEX_CALCULATION_EPSILON = 0.05;

const DEFAULT_WORKSPACE_RENDER_OPTIONS: RenderRWorkspaceOptions = {
renderComponents: {
header: true,
timePanel: true,
dateTable: true,
allDayPanel: true,
},
generateNewData: true,
};

class SchedulerWorkSpace extends WidgetObserver {
_viewDataProvider: any;

Expand Down Expand Up @@ -798,6 +820,7 @@ class SchedulerWorkSpace extends WidgetObserver {
currentDate: this.option('currentDate'),
startDate: this.option('startDate'),
firstDayOfWeek: this.option('firstDayOfWeek'),
showCurrentTimeIndicator: this.option('showCurrentTimeIndicator'),

...this.virtualScrollingDispatcher.getRenderState(),
};
Expand Down Expand Up @@ -2020,16 +2043,27 @@ class SchedulerWorkSpace extends WidgetObserver {
// Methods that render renovated components. Useless in renovation
// ------------

renderRWorkSpace(componentsToRender?: any) {
const allComponents = {
header: true, timePanel: true, dateTable: true, allDayPanel: true,
};
const components = componentsToRender ?? allComponents;
renderRWorkSpace({
header,
timePanel,
dateTable,
allDayPanel,
}: RenderComponentOptions = DEFAULT_WORKSPACE_RENDER_OPTIONS.renderComponents) {
if (header) {
this.renderRHeaderPanel();
}

if (timePanel) {
this.renderRTimeTable();
}

components.header && this.renderRHeaderPanel();
components.timePanel && this.renderRTimeTable();
components.dateTable && this.renderRDateTable();
components.allDayPanel && this.renderRAllDayPanel();
if (dateTable) {
this.renderRDateTable();
}

if (allDayPanel) {
this.renderRAllDayPanel();
}
}

renderRDateTable() {
Expand Down Expand Up @@ -2729,11 +2763,13 @@ class SchedulerWorkSpace extends WidgetObserver {
});
}

_renderDateTimeIndication() { return noop(); }
protected _renderDateTimeIndication() { return noop(); }

protected renderCurrentDateTimeLineAndShader(): void { return noop(); }

_setIndicationUpdateInterval() { return noop(); }
protected renderCurrentDateTimeIndication(): void { return noop(); }

_refreshDateTimeIndication() { return noop(); }
protected _setIndicationUpdateInterval() { return noop(); }

_detachGroupCountClass() {
[
Expand Down Expand Up @@ -2779,7 +2815,7 @@ class SchedulerWorkSpace extends WidgetObserver {
this._$allDayTitle && this._$allDayTitle.remove();
}

_cleanView() {
_cleanView(): void {
this.cache.clear();
this._cleanTableWidths();
this.cellsSelectionState.clearSelectedAndFocusedCells();
Expand Down Expand Up @@ -2892,14 +2928,18 @@ class SchedulerWorkSpace extends WidgetObserver {
}
}

renderWorkSpace(isGenerateNewViewData = true) {
renderWorkSpace({
generateNewData,
renderComponents,
} = DEFAULT_WORKSPACE_RENDER_OPTIONS): void {
this.cache.clear();

this.viewDataProvider.update(this.generateRenderOptions(), isGenerateNewViewData);
this.viewDataProvider.update(this.generateRenderOptions(), generateNewData);

if (this.isRenovatedRender()) {
this.renderRWorkSpace();
this.renderRWorkSpace(renderComponents);
} else {
// TODO Old render: Delete this old render block after the SSR tests check.
this._renderDateHeader();
this._renderTimePanel();
this._renderGroupAllDayPanel();
Expand Down
120 changes: 69 additions & 51 deletions js/__internal/scheduler/workspaces/m_work_space_indicator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { getBoundingRect } from '@js/core/utils/position';
import { setWidth } from '@js/core/utils/size';
import { hasWindow } from '@js/core/utils/window';
import { getToday } from '@js/renovation/ui/scheduler/view_model/to_test/views/utils/base';
import { dateUtilsTs } from '@ts/core/utils/date';

import { HEADER_CURRENT_TIME_CELL_CLASS } from '../m_classes';
import timezoneUtils from '../m_utils_time_zone';
Expand All @@ -21,10 +22,12 @@ class SchedulerWorkSpaceIndicator extends SchedulerWorkSpace {

// @ts-expect-error
_getToday() {
return getToday(this.option('indicatorTime') as any, this.timeZoneCalculator);
const viewOffset = this.option('viewOffset') as number;
const today = getToday(this.option('indicatorTime') as Date, this.timeZoneCalculator);
return dateUtilsTs.addOffsets(today, [-viewOffset]);
}

isIndicationOnView() {
isIndicationOnView(): boolean {
if (this.option('showCurrentTimeIndicator')) {
const today = this._getToday();
const endViewDate = dateUtils.trimTime(this.getEndViewDate());
Expand Down Expand Up @@ -56,24 +59,6 @@ class SchedulerWorkSpaceIndicator extends SchedulerWorkSpace {
return dateUtils.dateInRange(today, firstViewDate, endViewDate);
}

_renderDateTimeIndication() {
if (this.isIndicationAvailable()) {
if (this.option('shadeUntilCurrentTime')) {
this._shader.render();
}

if (this.isIndicationOnView() && this.isIndicatorVisible()) {
const groupCount = this._getGroupCount() || 1;
const $container = this._dateTableScrollable.$content();
const height = this.getIndicationHeight();
const rtlOffset = this._getRtlOffset(this.getCellWidth());

this._renderIndicator(height, rtlOffset, $container, groupCount);
this._setCurrentTimeCells();
}
}
}

_renderIndicator(height, rtlOffset, $container, groupCount) {
const groupedByDate = this.isGroupedByDate();
const repeatCount = groupedByDate ? 1 : groupCount;
Expand All @@ -99,15 +84,15 @@ class SchedulerWorkSpaceIndicator extends SchedulerWorkSpace {
return this.option('rtlEnabled') ? getBoundingRect(this._dateTableScrollable.$content().get(0)).width - this.getTimePanelWidth() - width : 0;
}

_setIndicationUpdateInterval() {
protected _setIndicationUpdateInterval() {
if (!this.option('showCurrentTimeIndicator') || this.option('indicatorUpdateInterval') === 0) {
return;
}

this._clearIndicatorUpdateInterval();

this._indicatorInterval = setInterval(() => {
this._refreshDateTimeIndication();
this.renderCurrentDateTimeIndication();
}, this.option('indicatorUpdateInterval'));
}

Expand Down Expand Up @@ -172,25 +157,27 @@ class SchedulerWorkSpaceIndicator extends SchedulerWorkSpace {
super._dispose.apply(this, arguments as any);
}

_refreshDateTimeIndication() {
this._cleanDateTimeIndicator();
this._cleanCurrentTimeCells();
renderCurrentDateTimeIndication(): void {
this.renderCurrentDateTimeLineAndShader();

if (this.isRenovatedRender()) {
this.renderWorkSpace({
generateNewData: true,
renderComponents: {
header: true,
timePanel: true,
},
});
}
}

renderCurrentDateTimeLineAndShader(): void {
this._cleanDateTimeIndicator();
this._shader?.clean();

this._renderDateTimeIndication();
}

_setCurrentTimeCells() {
const timePanelCells = this._getTimePanelCells();
const currentTimeCellIndices = this._getCurrentTimePanelCellIndices();
currentTimeCellIndices.forEach((timePanelCellIndex) => {
timePanelCells.eq(timePanelCellIndex)
.addClass(TIME_PANEL_CURRENT_TIME_CELL_CLASS);
});
}

_isCurrentTimeHeaderCell(headerIndex) {
_isCurrentTimeHeaderCell(headerIndex: number): boolean {
if (this.isIndicationOnView()) {
const { completeDateHeaderMap } = this.viewDataProvider;
const date = completeDateHeaderMap[completeDateHeaderMap.length - 1][headerIndex].startDate;
Expand Down Expand Up @@ -220,19 +207,13 @@ class SchedulerWorkSpaceIndicator extends SchedulerWorkSpace {
_dimensionChanged() {
super._dimensionChanged();

this._refreshDateTimeIndication();
this.renderCurrentDateTimeLineAndShader();
}

_cleanDateTimeIndicator() {
(this.$element() as any).find(`.${SCHEDULER_DATE_TIME_INDICATOR_CLASS}`).remove();
}

_cleanCurrentTimeCells() {
(this.$element() as any)
.find(`.${TIME_PANEL_CURRENT_TIME_CELL_CLASS}`)
.removeClass(TIME_PANEL_CURRENT_TIME_CELL_CLASS);
}

_cleanWorkSpace() {
super._cleanWorkSpace();

Expand All @@ -250,19 +231,13 @@ class SchedulerWorkSpaceIndicator extends SchedulerWorkSpace {
this._setIndicationUpdateInterval();
break;
case 'showAllDayPanel':
super._optionChanged(args);
this._refreshDateTimeIndication();
break;
case 'allDayExpanded':
super._optionChanged(args);
this._refreshDateTimeIndication();
break;
case 'crossScrollingEnabled':
super._optionChanged(args);
this._refreshDateTimeIndication();
this.renderCurrentDateTimeIndication();
break;
case 'shadeUntilCurrentTime':
this._refreshDateTimeIndication();
this.renderCurrentDateTimeIndication();
break;
default:
super._optionChanged(args);
Expand Down Expand Up @@ -307,6 +282,49 @@ class SchedulerWorkSpaceIndicator extends SchedulerWorkSpace {
...cellIndices.map((cellIndex) => rowCountPerGroup * groupIndex + cellIndex),
], []);
}

protected _renderDateTimeIndication(): void {
if (!this.isIndicationAvailable()) {
return;
}

if (this.option('shadeUntilCurrentTime')) {
this._shader.render();
}

if (!this.isIndicationOnView() || !this.isIndicatorVisible()) {
return;
}

const groupCount = this._getGroupCount() || 1;
const $container = this._dateTableScrollable.$content();
const height = this.getIndicationHeight();
const rtlOffset = this._getRtlOffset(this.getCellWidth());

this._renderIndicator(height, rtlOffset, $container, groupCount);

// TODO Old render: delete this code with the old render.
if (!this.isRenovatedRender()) {
this._setCurrentTimeCells();
}
}

// Temporary new render methods.
// TODO Old render: replace base call methods by these after the deleting of the old render.
protected _setCurrentTimeCells(): void {
const timePanelCells = this._getTimePanelCells();
const currentTimeCellIndices = this._getCurrentTimePanelCellIndices();
currentTimeCellIndices.forEach((timePanelCellIndex) => {
timePanelCells.eq(timePanelCellIndex)
.addClass(TIME_PANEL_CURRENT_TIME_CELL_CLASS);
});
}

protected _cleanCurrentTimeCells(): void {
(this.$element() as any)
.find(`.${TIME_PANEL_CURRENT_TIME_CELL_CLASS}`)
.removeClass(TIME_PANEL_CURRENT_TIME_CELL_CLASS);
}
}

registerComponent('dxSchedulerWorkSpace', SchedulerWorkSpaceIndicator as any);
Expand Down
Loading

0 comments on commit 2858871

Please sign in to comment.