-
Notifications
You must be signed in to change notification settings - Fork 665
Scheduler - Appointment Form - Fix KBN issues #32225
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
Changes from all commits
23f4757
9a9adcc
20d4e5c
d6d6627
5c0fad2
4508f6f
f43d6b9
8b6da60
832bb6f
b538a5e
b704ae9
aacfa87
e241377
4b0cbea
249c87a
d2c2ba7
61e4449
e81e406
287dd19
bf70cd0
68ce4eb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,62 @@ | ||
| import Scheduler from 'devextreme-testcafe-models/scheduler'; | ||
| import { createWidget } from '../../../../helpers/createWidget'; | ||
| import url from '../../../../helpers/getPageUrl'; | ||
|
|
||
| fixture.disablePageReloads`Appointment Form: Functional` | ||
| .page(url(__dirname, '../../../container.html')); | ||
|
|
||
| const SCHEDULER_SELECTOR = '#container'; | ||
|
|
||
| test('Subject text editor should have focus after returning from recurrence form', async (t) => { | ||
| const appointment = { | ||
| text: 'Appointment', | ||
| startDate: new Date('2021-04-26T16:30:00.000Z'), | ||
| endDate: new Date('2021-04-26T18:30:00.000Z'), | ||
| allDay: false, | ||
| recurrenceRule: 'FREQ=WEEKLY;BYDAY=MO,TH;COUNT=10', | ||
| }; | ||
|
|
||
| const scheduler = new Scheduler(SCHEDULER_SELECTOR); | ||
| const appointmentPopup = await scheduler.openAppointmentPopup(t, appointment, true); | ||
|
|
||
| await appointmentPopup.openRecurrenceSettings(t); | ||
|
|
||
| await t.click(appointmentPopup.recurrence.backButton); | ||
|
|
||
| await t | ||
| .expect(appointmentPopup.textEditor.getInput().focused) | ||
| .ok(); | ||
| }).before(async () => { | ||
| await createWidget('dxScheduler', { | ||
| dataSource: [], | ||
| views: ['week'], | ||
| currentView: 'week', | ||
| currentDate: new Date(2021, 2, 25), | ||
| }); | ||
| }); | ||
|
|
||
| test('Recurrence start date editor should have focus after opening recurrence settings', async (t) => { | ||
| const appointment = { | ||
| text: 'Appointment', | ||
| startDate: new Date('2021-04-26T16:30:00.000Z'), | ||
| endDate: new Date('2021-04-26T18:30:00.000Z'), | ||
| allDay: false, | ||
| recurrenceRule: 'FREQ=WEEKLY;BYDAY=MO,TH;COUNT=10', | ||
| }; | ||
|
|
||
| const scheduler = new Scheduler(SCHEDULER_SELECTOR); | ||
| const appointmentPopup = await scheduler.openAppointmentPopup(t, appointment, true); | ||
|
|
||
| await appointmentPopup.openRecurrenceSettings(t); | ||
|
|
||
| await t | ||
| .expect(appointmentPopup.recurrence.startDateInput.focused) | ||
| .ok(); | ||
| }).before(async () => { | ||
| await createWidget('dxScheduler', { | ||
| dataSource: [], | ||
| views: ['week'], | ||
| currentView: 'week', | ||
| currentDate: new Date(2021, 2, 25), | ||
| }); | ||
| }); | ||
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -1337,9 +1337,9 @@ describe('Appointment Form', () => { | |||||||
| scheduler.showAppointmentPopup(); | ||||||||
|
|
||||||||
| expect(POM.popup.isMainGroupVisible()).toBe(true); | ||||||||
| expect(POM.popup.mainGroup?.getAttribute('tabindex')).toBeNull(); | ||||||||
| expect(POM.popup.mainGroup?.getAttribute('inert')).toBeNull(); | ||||||||
| expect(POM.popup.isRecurrenceGroupVisible()).toBe(false); | ||||||||
| expect(POM.popup.recurrenceGroup?.getAttribute('tabindex')).toBe('-1'); | ||||||||
| expect(POM.popup.recurrenceGroup?.getAttribute('inert')).toBe('true'); | ||||||||
|
|
||||||||
| POM.popup.selectRepeatValue('weekly'); | ||||||||
| await new Promise(process.nextTick); | ||||||||
|
|
@@ -1349,17 +1349,17 @@ describe('Appointment Form', () => { | |||||||
| expect(typeof popupHeight).toBe('number'); | ||||||||
|
|
||||||||
| expect(POM.popup.isMainGroupVisible()).toBe(false); | ||||||||
| expect(POM.popup.mainGroup?.getAttribute('tabindex')).toBe('-1'); | ||||||||
| expect(POM.popup.mainGroup?.getAttribute('inert')).toBe('true'); | ||||||||
| expect(POM.popup.isRecurrenceGroupVisible()).toBe(true); | ||||||||
| expect(POM.popup.recurrenceGroup?.getAttribute('tabindex')).toBeNull(); | ||||||||
| expect(POM.popup.recurrenceGroup?.getAttribute('inert')).toBeNull(); | ||||||||
|
|
||||||||
| POM.popup.getBackButton().click(); | ||||||||
|
|
||||||||
| expect(POM.popup.component.option('height')).toBe('auto'); | ||||||||
| expect(POM.popup.isMainGroupVisible()).toBe(true); | ||||||||
| expect(POM.popup.mainGroup?.getAttribute('tabindex')).toBeNull(); | ||||||||
| expect(POM.popup.mainGroup?.getAttribute('inert')).toBeNull(); | ||||||||
| expect(POM.popup.isRecurrenceGroupVisible()).toBe(false); | ||||||||
| expect(POM.popup.recurrenceGroup?.getAttribute('tabindex')).toBe('-1'); | ||||||||
| expect(POM.popup.recurrenceGroup?.getAttribute('inert')).toBe('true'); | ||||||||
| }); | ||||||||
|
|
||||||||
| it('should open main form when opening recurring appointment', async () => { | ||||||||
|
|
@@ -1676,6 +1676,52 @@ describe('Appointment Form', () => { | |||||||
| }); | ||||||||
| }); | ||||||||
| }); | ||||||||
|
|
||||||||
| describe('FrequencyEditor focus', () => { | ||||||||
| it('should not be focused when value is changed via API', async () => { | ||||||||
| const { POM, scheduler } = await createScheduler({ | ||||||||
| ...getDefaultConfig(), | ||||||||
| dataSource: [], | ||||||||
| views: ['week'], | ||||||||
| currentView: 'week', | ||||||||
| currentDate: new Date(2021, 2, 25), | ||||||||
| }); | ||||||||
|
|
||||||||
| scheduler.showAppointmentPopup(recurringAppointment); | ||||||||
| POM.popup.getEditSeriesButton().click(); | ||||||||
| POM.popup.openRecurrenceSettings(); | ||||||||
|
|
||||||||
| const frequencyEditor = POM.popup.form.getEditor('recurrencePeriodEditor'); | ||||||||
| const frequencyEditorInputElement = POM.popup.getInput('recurrencePeriodEditor').get(0) as HTMLElement; | ||||||||
|
|
||||||||
| frequencyEditor?.option('value', 'yearly'); | ||||||||
|
|
||||||||
| expect(document.activeElement).not.toBe(frequencyEditorInputElement); | ||||||||
| }); | ||||||||
|
|
||||||||
| it('should be focused when value is changed via keyboard', async () => { | ||||||||
| const { POM, scheduler, keydown } = await createScheduler({ | ||||||||
| ...getDefaultConfig(), | ||||||||
| dataSource: [], | ||||||||
| views: ['week'], | ||||||||
| currentView: 'week', | ||||||||
| currentDate: new Date(2021, 2, 25), | ||||||||
| }); | ||||||||
|
|
||||||||
| scheduler.showAppointmentPopup(recurringAppointment); | ||||||||
| POM.popup.getEditSeriesButton().click(); | ||||||||
| POM.popup.openRecurrenceSettings(); | ||||||||
|
|
||||||||
| const frequencyEditorInputElement = POM.popup.getInput('recurrencePeriodEditor').get(0) as HTMLElement; | ||||||||
|
|
||||||||
| frequencyEditorInputElement.click(); | ||||||||
| jest.useFakeTimers(); | ||||||||
| keydown(frequencyEditorInputElement, 'ArrowDown'); | ||||||||
| jest.runAllTimers(); | ||||||||
|
||||||||
| jest.runAllTimers(); | |
| jest.runAllTimers(); | |
| jest.useRealTimers(); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -22,6 +22,7 @@ const CLASSES = { | |
| recurrenceGroup: 'dx-scheduler-form-recurrence-group', | ||
| recurrenceHidden: 'dx-scheduler-form-recurrence-group-hidden', | ||
|
|
||
| recurrenceStartDateEditor: 'dx-scheduler-form-recurrence-start-date-editor', | ||
| frequencyEditor: 'dx-scheduler-form-recurrence-frequency-editor', | ||
| byMonthEditor: 'dx-scheduler-form-recurrence-by-month-editor', | ||
| dayOfMonthEditor: 'dx-scheduler-form-day-of-month-editor', | ||
|
|
@@ -216,6 +217,7 @@ export class RecurrenceForm { | |
| getStartDateCommonConfig(this.scheduler.getFirstDayOfWeek()), | ||
| { | ||
| name: EDITOR_NAMES.recurrenceStartDateEditor, | ||
| cssClass: CLASSES.recurrenceStartDateEditor, | ||
| label: { | ||
| text: messageLocalization.format('dxScheduler-editorLabelStartDate'), | ||
| }, | ||
|
|
@@ -269,6 +271,10 @@ export class RecurrenceForm { | |
| } | ||
|
|
||
| private createRecurrenceRuleGroup(): GroupItem { | ||
| // Change of frequency editor's value causes rerender of the recurrencePatternGroup. | ||
| // To prevent focus loss in this editor, we use this flag. | ||
| let needRestoreFrequencyEditorFocus = false; | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The reason of focus loss is because Another solution is to wrap weekGroup, monthGroup and yearGroup into different group here. I have decided to use this flag, because it's used in very narrow scope and because form items already have very deep nesting (docs). But if you have any objections, let's discuss it :) |
||
|
|
||
| return { | ||
| itemType: 'group', | ||
| name: GROUP_NAMES.recurrenceRuleRepeatGroup, | ||
|
|
@@ -314,6 +320,13 @@ export class RecurrenceForm { | |
| displayExpr: 'text', | ||
| onContentReady: (e): void => { | ||
| e.component.option('value', this.recurrenceRule.frequency); | ||
|
|
||
| if (needRestoreFrequencyEditorFocus) { | ||
| setTimeout(() => { | ||
| e.component.focus(); | ||
| needRestoreFrequencyEditorFocus = false; | ||
| }); | ||
| } | ||
| }, | ||
| onValueChanged: (e): void => { | ||
| const previousValue = this.recurrenceRule.frequency; | ||
|
|
@@ -322,6 +335,10 @@ export class RecurrenceForm { | |
| return; | ||
| } | ||
|
|
||
| if (e.event) { | ||
| needRestoreFrequencyEditorFocus = true; | ||
| } | ||
|
|
||
| this.recurrenceRule.frequency = e.value; | ||
| this.updateDayEditorsVisibility(); | ||
| }, | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.