-
Notifications
You must be signed in to change notification settings - Fork 663
Scheduler: T1310544 — scrollTo does not take offset into account #32073
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
sjbur
wants to merge
10
commits into
DevExpress:26_1
Choose a base branch
from
sjbur:issue-2570_26_1
base: 26_1
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+342
−101
Open
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
7f828cf
fix: fix bug
sjbur 37a82c0
test: reerrange tests
sjbur d67c7df
feat: try to fix bug with new strategy
sjbur 3962f46
fix: fix indents
sjbur 4565841
fix: fix indents
sjbur 14b1190
fix: short comments
sjbur 0ac5ddd
fix: revert jquery
sjbur 529130c
feat: optimize code
sjbur 82d04c0
feat: optimize code
sjbur ead33a0
feat: update fix
sjbur File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
79 changes: 0 additions & 79 deletions
79
packages/devextreme/js/__internal/scheduler/__tests__/workspace.recalculation.test.ts
This file was deleted.
Oops, something went wrong.
303 changes: 303 additions & 0 deletions
303
packages/devextreme/js/__internal/scheduler/__tests__/workspace.test.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,303 @@ | ||
| import { | ||
| afterEach, beforeEach, describe, expect, it, jest, | ||
| } from '@jest/globals'; | ||
| import $ from '@js/core/renderer'; | ||
| import { getWidth } from '@js/core/utils/size'; | ||
|
|
||
| import fx from '../../../common/core/animation/fx'; | ||
| import CustomStore from '../../../data/custom_store'; | ||
| import { createScheduler } from './__mock__/create_scheduler'; | ||
| import { setupSchedulerTestEnvironment } from './__mock__/m_mock_scheduler'; | ||
|
|
||
| const CLASSES = { | ||
| scheduler: 'dx-scheduler', | ||
| workSpace: 'dx-scheduler-work-space', | ||
| }; | ||
|
|
||
| describe('Workspace', () => { | ||
| describe('Recalculation with Async Templates (T661335)', () => { | ||
| beforeEach(() => { | ||
| fx.off = true; | ||
| setupSchedulerTestEnvironment({ height: 600 }); | ||
| }); | ||
|
|
||
| afterEach(() => { | ||
| const $scheduler = $(document.querySelector(`.${CLASSES.scheduler}`)); | ||
| // @ts-expect-error | ||
| $scheduler.dxScheduler('dispose'); | ||
| document.body.innerHTML = ''; | ||
| fx.off = false; | ||
| }); | ||
|
|
||
| it('should not duplicate workspace elements when resources are loaded asynchronously (T661335)', async () => { | ||
| const { scheduler, container } = await createScheduler({ | ||
| templatesRenderAsynchronously: true, | ||
| currentView: 'day', | ||
| views: ['day'], | ||
| groups: ['owner'], | ||
| resources: [ | ||
| { | ||
| fieldExpr: 'owner', | ||
| dataSource: [{ id: 1, text: 'Owner 1' }], | ||
| }, | ||
| { | ||
| fieldExpr: 'room', | ||
| dataSource: new CustomStore({ | ||
| load(): Promise<unknown> { | ||
| return new Promise((resolve) => { | ||
| setTimeout(() => { | ||
| resolve([{ id: 1, text: 'Room 1', color: '#ff0000' }]); | ||
| }); | ||
| }); | ||
| }, | ||
| }), | ||
| }, | ||
| ], | ||
| dataSource: [ | ||
| { | ||
| text: 'Meeting in Room 1', | ||
| startDate: new Date(2017, 4, 25, 9, 0), | ||
| endDate: new Date(2017, 4, 25, 10, 0), | ||
| roomId: 1, | ||
| }, | ||
| ], | ||
| startDayHour: 9, | ||
| currentDate: new Date(2017, 4, 25), | ||
| height: 600, | ||
| }); | ||
|
|
||
| scheduler.option('groups', ['room']); | ||
|
|
||
| await new Promise((r) => { setTimeout(r); }); | ||
|
|
||
| const $workSpaces = $(container).find(`.${CLASSES.workSpace}`); | ||
| const $groupHeader = $(container).find('.dx-scheduler-group-header'); | ||
|
|
||
| expect($workSpaces.length).toBe(1); | ||
|
|
||
| expect($groupHeader.length).toBeGreaterThan(0); | ||
| expect($groupHeader.text()).toContain('Room 1'); | ||
| }); | ||
| }); | ||
|
|
||
| describe('scrollTo', () => { | ||
| beforeEach(() => { | ||
| fx.off = true; | ||
| setupSchedulerTestEnvironment({ height: 600 }); | ||
| }); | ||
|
|
||
| afterEach(() => { | ||
| document.body.innerHTML = ''; | ||
| fx.off = false; | ||
| }); | ||
sjbur marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| it('T1310544: should scroll to date with offset: 720 (12 hours)', async () => { | ||
| const { scheduler } = await createScheduler({ | ||
| views: ['timelineDay'], | ||
| currentView: 'timelineDay', | ||
| currentDate: new Date(2021, 1, 2), | ||
| firstDayOfWeek: 0, | ||
| startDayHour: 6, | ||
| endDayHour: 18, | ||
| offset: 720, | ||
| cellDuration: 60, | ||
| height: 580, | ||
| }); | ||
|
|
||
| const workspace = scheduler.getWorkSpace(); | ||
| const scrollable = workspace.getScrollable(); | ||
| const $scrollable = scrollable.$element(); | ||
| const scrollBySpy = jest.spyOn(scrollable, 'scrollBy'); | ||
|
|
||
| // With offset: 720 (12 hours), cells start at 18:00 (6:00 + 12h) | ||
| // For date 22:00, this should be cell index 4 (18:00=0, 19:00=1, 20:00=2, 21:00=3, 22:00=4) | ||
| const leftCellCount = 4; | ||
| const cellWidth = workspace.getCellWidth(); | ||
| const scrollableWidth = getWidth($scrollable); | ||
| const expectedLeft = leftCellCount * cellWidth - (scrollableWidth - cellWidth) / 2; | ||
|
|
||
| const targetDate = new Date(2021, 1, 2, 22, 0); | ||
| scheduler.scrollTo(targetDate, undefined, false); | ||
|
|
||
| expect(scrollBySpy).toHaveBeenCalledTimes(1); | ||
| const scrollParams = scrollBySpy.mock.calls[0][0] as { left: number; top: number }; | ||
| expect(scrollParams.left).toBeCloseTo(expectedLeft, 1); | ||
|
|
||
| scrollBySpy.mockRestore(); | ||
| }); | ||
sjbur marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| it('should scroll to date with offset after midnight: 720 (12 hours)', async () => { | ||
| const { scheduler } = await createScheduler({ | ||
| views: ['timelineDay'], | ||
| currentView: 'timelineDay', | ||
| currentDate: new Date(2021, 1, 2), | ||
| firstDayOfWeek: 0, | ||
| startDayHour: 6, | ||
| endDayHour: 18, | ||
| offset: 720, | ||
| cellDuration: 60, | ||
| height: 580, | ||
| }); | ||
|
|
||
| const workspace = scheduler.getWorkSpace(); | ||
| const scrollable = workspace.getScrollable(); | ||
| const $scrollable = scrollable.$element(); | ||
| const scrollBySpy = jest.spyOn(scrollable, 'scrollBy'); | ||
|
|
||
| // With offset: 720 (12 hours), cells start at 18:00 (6:00 + 12h) | ||
| // For date 3 feb 04:00, this should be cell index 10 (18:00=0, 19:00=1, ... 04:00=10) | ||
| const leftCellCount = 10; | ||
| const cellWidth = workspace.getCellWidth(); | ||
| const scrollableWidth = getWidth($scrollable); | ||
| const expectedLeft = leftCellCount * cellWidth - (scrollableWidth - cellWidth) / 2; | ||
|
|
||
| const targetDate = new Date(2021, 1, 3, 4, 0); | ||
| scheduler.scrollTo(targetDate, undefined, false); | ||
|
|
||
| expect(scrollBySpy).toHaveBeenCalledTimes(1); | ||
| const scrollParams = scrollBySpy.mock.calls[0][0] as { left: number; top: number }; | ||
| expect(scrollParams.left).toBeCloseTo(expectedLeft, 1); | ||
|
|
||
| scrollBySpy.mockRestore(); | ||
| }); | ||
|
|
||
| it('should scroll to end of day', async () => { | ||
| const { scheduler } = await createScheduler({ | ||
| views: ['timelineWeek'], | ||
| currentView: 'timelineWeek', | ||
| currentDate: new Date(2021, 1, 2), | ||
| firstDayOfWeek: 0, | ||
| startDayHour: 6, | ||
| endDayHour: 18, | ||
| offset: 120, | ||
| cellDuration: 60, | ||
| height: 580, | ||
| }); | ||
|
|
||
| const workspace = scheduler.getWorkSpace(); | ||
| const scrollable = workspace.getScrollable(); | ||
| const $scrollable = scrollable.$element(); | ||
| const scrollBySpy = jest.spyOn(scrollable, 'scrollBy'); | ||
|
|
||
| // With offset: 720 (12 hours), cells start at 18:00 (6:00 + 12h) | ||
| // For date 3 feb 04:00, this should be cell index 3 (18:00=0, ... 22:00=35) | ||
| const leftCellCount = 35; | ||
| const cellWidth = workspace.getCellWidth(); | ||
| const scrollableWidth = getWidth($scrollable); | ||
| const expectedLeft = leftCellCount * cellWidth - (scrollableWidth - cellWidth) / 2; | ||
|
|
||
| const targetDate = new Date(2021, 1, 2, 22, 0); | ||
| scheduler.scrollTo(targetDate, undefined, false); | ||
|
|
||
| expect(scrollBySpy).toHaveBeenCalledTimes(1); | ||
| const scrollParams = scrollBySpy.mock.calls[0][0] as { left: number; top: number }; | ||
| expect(scrollParams.left).toBeCloseTo(expectedLeft, 1); | ||
|
|
||
| scrollBySpy.mockRestore(); | ||
| }); | ||
|
|
||
| describe('hour normalization', () => { | ||
| it('should normalize hours to visible range without viewOffset', async () => { | ||
| const { scheduler } = await createScheduler({ | ||
| views: ['timelineDay'], | ||
| currentView: 'timelineDay', | ||
| currentDate: new Date(2021, 1, 2), | ||
| startDayHour: 6, | ||
| endDayHour: 18, | ||
| offset: 0, | ||
| }); | ||
|
|
||
| const workspace = scheduler.getWorkSpace(); | ||
| const scrollable = workspace.getScrollable(); | ||
| const scrollBySpy = jest.spyOn(scrollable, 'scrollBy'); | ||
|
|
||
| // Below startDayHour (6), should NOT normalize to 6 (?) | ||
| const dateBelowRange = new Date(2021, 1, 2, 4, 0); | ||
| scheduler.scrollTo(dateBelowRange, undefined, false); | ||
| expect(scrollBySpy).not.toHaveBeenCalled(); | ||
|
|
||
| scrollBySpy.mockClear(); | ||
| // Above endDayHour (18), should NOT normalize to 17 (?) | ||
| const dateAboveRange = new Date(2021, 1, 2, 20, 0); | ||
| scheduler.scrollTo(dateAboveRange, undefined, false); | ||
| expect(scrollBySpy).not.toHaveBeenCalled(); | ||
|
|
||
| scrollBySpy.mockClear(); | ||
| // Within range [6, 18), should scroll normally | ||
| const dateInRange = new Date(2021, 1, 2, 12, 0); | ||
| scheduler.scrollTo(dateInRange, undefined, false); | ||
| expect(scrollBySpy).toHaveBeenCalled(); | ||
|
|
||
| scrollBySpy.mockRestore(); | ||
| }); | ||
|
|
||
| it('should normalize hours to visible range with viewOffset (no midnight crossing)', async () => { | ||
| const { scheduler } = await createScheduler({ | ||
| views: ['timelineDay'], | ||
| currentView: 'timelineDay', | ||
| currentDate: new Date(2021, 1, 2), | ||
| startDayHour: 6, | ||
| endDayHour: 18, | ||
| offset: 360, | ||
| }); | ||
|
|
||
| const workspace = scheduler.getWorkSpace(); | ||
| const scrollable = workspace.getScrollable(); | ||
| const scrollBySpy = jest.spyOn(scrollable, 'scrollBy'); | ||
|
|
||
| // Below adjustedStartDayHour (12), should NOT normalize to 12 (?) | ||
| const dateBelowAdjustedRange = new Date(2021, 1, 2, 10, 0); | ||
| scheduler.scrollTo(dateBelowAdjustedRange, undefined, false); | ||
| expect(scrollBySpy).not.toHaveBeenCalled(); | ||
|
|
||
| scrollBySpy.mockClear(); | ||
| // Within adjusted range [12, 24), should scroll normally | ||
| const dateInAdjustedRange = new Date(2021, 1, 2, 15, 0); | ||
| scheduler.scrollTo(dateInAdjustedRange, undefined, false); | ||
| expect(scrollBySpy).toHaveBeenCalled(); | ||
|
|
||
| scrollBySpy.mockRestore(); | ||
| }); | ||
|
|
||
| it('should normalize hours to visible range with viewOffset (midnight crossing)', async () => { | ||
| const { scheduler } = await createScheduler({ | ||
| views: ['timelineDay'], | ||
| currentView: 'timelineDay', | ||
| currentDate: new Date(2021, 1, 2), | ||
| startDayHour: 6, | ||
| endDayHour: 18, | ||
| offset: 720, | ||
| }); | ||
|
|
||
| const workspace = scheduler.getWorkSpace(); | ||
| const scrollable = workspace.getScrollable(); | ||
| const scrollBySpy = jest.spyOn(scrollable, 'scrollBy'); | ||
|
|
||
| // In gap [6, 18), should NOT normalize to 18:00 Feb 2 (?) | ||
| const dateInGap = new Date(2021, 1, 2, 10, 0); | ||
| scheduler.scrollTo(dateInGap, undefined, false); | ||
| expect(scrollBySpy).not.toHaveBeenCalled(); | ||
|
|
||
| scrollBySpy.mockClear(); | ||
| // In range [18, 24) on Feb 2, should scroll normally | ||
| const dateInFirstRange = new Date(2021, 1, 2, 22, 0); | ||
| scheduler.scrollTo(dateInFirstRange, undefined, false); | ||
| expect(scrollBySpy).toHaveBeenCalled(); | ||
|
|
||
| scrollBySpy.mockClear(); | ||
| // In range [0, 6) but on wrong day (Feb 2), should NOT normalize to 18:00 Feb 2 (?) | ||
| const dateInSecondRangeWrongDay = new Date(2021, 1, 2, 3, 0); | ||
| scheduler.scrollTo(dateInSecondRangeWrongDay, undefined, false); | ||
| expect(scrollBySpy).not.toHaveBeenCalled(); | ||
|
|
||
| scrollBySpy.mockClear(); | ||
| // In range [0, 6) on correct day (Feb 3), should scroll normally | ||
| const dateInSecondRangeCorrectDay = new Date(2021, 1, 3, 3, 0); | ||
| scheduler.scrollTo(dateInSecondRangeCorrectDay, undefined, false); | ||
| expect(scrollBySpy).toHaveBeenCalled(); | ||
|
|
||
| scrollBySpy.mockRestore(); | ||
| }); | ||
| }); | ||
| }); | ||
| }); | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.