Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions e2e/testcafe-devextreme/tests/scheduler/common/scrollTo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,3 +230,91 @@ test('ScrollTo works correctly in timeline RTL (native, sync header/workspace)',
height: 580,
rtlEnabled: true,
}));

[
// startDayHour: 6:00, endDayHour: 18:00
{
offset: 0,
targetDate: new Date(2021, 1, 3, 4, 0),
expectedDate: new Date(2021, 1, 3, 6, 0),
},
{
offset: 0,
targetDate: new Date(2021, 1, 3, 12, 0),
expectedDate: new Date(2021, 1, 3, 12, 0),
},
{
offset: 0,
targetDate: new Date(2021, 1, 3, 20, 0),
expectedDate: new Date(2021, 1, 3, 18, 0),
},

// startDayHour: 18:00, endDayHour: next day 6:00
{
offset: 720,
targetDate: new Date(2021, 1, 3, 10, 0),
expectedDate: new Date(2021, 1, 3, 6, 0),
},
{
offset: 720,
targetDate: new Date(2021, 1, 3, 20, 0),
expectedDate: new Date(2021, 1, 3, 20, 0),
},
{
offset: 720,
targetDate: new Date(2021, 1, 4, 1, 0),
expectedDate: new Date(2021, 1, 4, 1, 0),
},
{
offset: 720,
targetDate: new Date(2021, 1, 4, 7, 0),
expectedDate: new Date(2021, 1, 4, 6, 0),
},

// startDayHour: prev day 18:00, endDayHour: 6:00
{
offset: -720,
targetDate: new Date(2021, 1, 3, 16, 0),
expectedDate: new Date(2021, 1, 3, 18, 0),
},
{
offset: -720,
targetDate: new Date(2021, 1, 3, 21, 0),
expectedDate: new Date(2021, 1, 3, 21, 0),
},
{
offset: -720,
targetDate: new Date(2021, 1, 4, 3, 0),
expectedDate: new Date(2021, 1, 4, 3, 0),
},
{
offset: -720,
targetDate: new Date(2021, 1, 3, 7, 0),
expectedDate: new Date(2021, 1, 3, 6, 0),
},
].forEach(({ offset, targetDate, expectedDate }) => {
test(`scrollTo should scroll to date with offset=${offset}, targetDate=${targetDate.toString()} (T1310544)`, async (t) => {
const scheduler = new Scheduler('#container');

await scheduler.scrollTo(targetDate);

const cellData = await scheduler.getCellDataAtViewportCenter();

await t
.expect(expectedDate.getTime()).gte(cellData.startDate.getTime())
// eslint-disable-next-line spellcheck/spell-checker
.expect(expectedDate.getTime()).lte(cellData.endDate.getTime());
}).before(async () => createScheduler({
dataSource: [],
views: [{
type: 'timelineWeek',
offset,
cellDuration: 60,
}],
currentView: 'timelineWeek',
currentDate: new Date(2021, 1, 2),
startDayHour: 6,
endDayHour: 18,
height: 580,
}));
});
Original file line number Diff line number Diff line change
Expand Up @@ -1407,26 +1407,20 @@ class SchedulerWorkSpace extends Widget<WorkspaceOptionsInternal> {
return (this.$element() as any).find(`.${GROUP_HEADER_CLASS}`);
}

_getScrollCoordinates(hours, minutes, date, groupIndex?: any, allDay?: any) {
_getScrollCoordinates(date, groupIndex?: any, allDay?: any) {
const currentDate = date || new Date(this.option('currentDate'));
const startDayHour = this.option('startDayHour');
const endDayHour = this.option('endDayHour');

if (hours < startDayHour) {
hours = startDayHour;
}
const cell = this.viewDataProvider.findGlobalCellPosition(currentDate, groupIndex, allDay, true);

if (hours >= endDayHour) {
hours = endDayHour - 1;
if (!cell) {
return undefined;
}

currentDate.setHours(hours, minutes, 0, 0);

const cell = this.viewDataProvider.findGlobalCellPosition(currentDate, groupIndex, allDay);
currentDate.setHours(cell.cellData.startDate.getHours(), currentDate.getMinutes(), 0, 0);

return this.virtualScrollingDispatcher.calculateCoordinatesByDataAndPosition(
cell?.cellData,
cell?.position,
cell.cellData,
cell.position,
currentDate,
isDateAndTimeView(this.type as any),
this.viewDirection === 'vertical',
Expand Down Expand Up @@ -1833,7 +1827,11 @@ class SchedulerWorkSpace extends Widget<WorkspaceOptionsInternal> {
: 0;
const isScrollToAllDay = allDay && this.isAllDayPanelVisible;

const coordinates = this._getScrollCoordinates(date.getHours(), date.getMinutes(), date, groupIndex, isScrollToAllDay);
const coordinates = this._getScrollCoordinates(date, groupIndex, isScrollToAllDay);

if (!coordinates) {
return;
}

const scrollable = this.getScrollable();
const $scrollable = scrollable.$element();
Expand Down Expand Up @@ -1865,8 +1863,9 @@ class SchedulerWorkSpace extends Widget<WorkspaceOptionsInternal> {
}

_isValidScrollDate(date, throwWarning = true) {
const min = this.getStartViewDate();
const max = this.getEndViewDate();
const viewOffset = this.option('viewOffset') as number;
const min = new Date(this.getStartViewDate().getTime() + viewOffset);
const max = new Date(this.getEndViewDate().getTime() + viewOffset);

if (date < min || date > max) {
throwWarning && errors.log('W1008', date);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -282,51 +282,67 @@ export default class ViewDataProvider {
return startDate < groupEndDate && endDate > groupStartDate;
}

findGlobalCellPosition(date, groupIndex = 0, allDay = false) {
findGlobalCellPosition(date, groupIndex = 0, allDay = false, findClosest = false) {
const { completeViewDataMap } = this;

const showAllDayPanel = this._options.isAllDayPanelVisible;

let resultDiff = Number.MAX_VALUE;
let resultCellData: ViewCellData | undefined;
let resultCellColumnIndex = -1;
let resultCellRowIndex = -1;

const getCellPosition = (columnIndex: number, rowIndex: number) => ({
columnIndex,
rowIndex: showAllDayPanel && !this._options.isVerticalGrouping
? rowIndex - 1
: rowIndex,
});

for (let rowIndex = 0; rowIndex < completeViewDataMap.length; rowIndex += 1) {
const currentRow = completeViewDataMap[rowIndex];

for (let columnIndex = 0; columnIndex < currentRow.length; columnIndex += 1) {
const cellData = currentRow[columnIndex];
const {
startDate: currentStartDate,
endDate: currentEndDate,
groupIndex: currentGroupIndex,
allDay: currentAllDay,
startDate: cellStartDate,
endDate: cellEndDate,
groupIndex: cellGroupIndex,
allDay: cellAllDay,
} = cellData;

if (groupIndex === currentGroupIndex
&& allDay === Boolean(currentAllDay)
&& this._compareDatesAndAllDay(date, currentStartDate, currentEndDate, allDay)) {
if (groupIndex !== cellGroupIndex || allDay !== Boolean(cellAllDay)) {
continue;
}

const isDateInCell = allDay
? dateUtils.sameDate(date, cellStartDate)
: date >= cellStartDate && date < cellEndDate;

if (isDateInCell) {
return {
position: {
columnIndex,
rowIndex: showAllDayPanel && !this._options.isVerticalGrouping
? rowIndex - 1
: rowIndex,
},
position: getCellPosition(columnIndex, rowIndex),
cellData,
};
}

const diff = Math.abs(date.getTime() - cellStartDate.getTime());

if (findClosest && diff < resultDiff) {
resultDiff = diff;
resultCellData = cellData;
resultCellColumnIndex = columnIndex;
resultCellRowIndex = rowIndex;
}
}
}

return undefined;
}

private _compareDatesAndAllDay(
date: Date,
cellStartDate: Date,
cellEndDate: Date,
allDay: boolean,
): boolean {
return allDay
? dateUtils.sameDate(date, cellStartDate)
: date >= cellStartDate && date < cellEndDate;
return resultCellData
? {
position: getCellPosition(resultCellColumnIndex, resultCellRowIndex),
cellData: resultCellData,
}
: undefined;
}

getSkippedDaysCount(groupIndex, startDate, endDate, daysCount) {
Expand Down
36 changes: 30 additions & 6 deletions packages/testcafe-models/scheduler/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,28 @@ export default class Scheduler extends Widget {
return cells.filter(`.${CLASS.focusedCell}`);
}

getCellDataAtViewportCenter(): any {
const { getInstance } = this;

return ClientFunction(
() => {
const instance = getInstance() as any;
const workSpace = instance.getWorkSpace();
const scrollable = workSpace.getScrollable();
const scrollLeft = scrollable.scrollLeft();
const scrollTop = scrollable.scrollTop();
const centerX = scrollLeft + scrollable.$element().width() / 2;
const centerY = scrollTop + scrollable.$element().height() / 2;

const cellElement = workSpace.getCellByCoordinates({ top: centerY, left: centerX }, false);
const cellData = workSpace.getCellData(cellElement);

return cellData;
},
{ dependencies: { getInstance } }
)();
}

getSelectedCells(isAllDay = false): Selector {
const cells = isAllDay ? this.allDayTableCells : this.dateTableCells;

Expand Down Expand Up @@ -197,13 +219,15 @@ export default class Scheduler extends Widget {

scrollTo(date: Date, group?: Record<string, unknown>, allDay?: boolean): Promise<any> {
const { getInstance } = this;
const scrollTo = (): any => (getInstance() as any).scrollTo(date, group, allDay);

return ClientFunction(scrollTo, {
dependencies: {
date, group, allDay, getInstance,
},
})();
return ClientFunction(
() => {
const instance = getInstance() as any;
instance.scrollTo(date, group, allDay);
}, {
dependencies: { date, group, allDay, getInstance },
}
)();
}

hideAppointmentTooltip(): Promise<any> {
Expand Down
Loading