@@ -5,8 +5,6 @@ import { name as dblclickEvent } from '@js/common/core/events/double_click';
55import { addNamespace , isFakeClickEvent } from '@js/common/core/events/utils/index' ;
66import registerComponent from '@js/core/component_registrator' ;
77import domAdapter from '@js/core/dom_adapter' ;
8- import { getPublicElement } from '@js/core/element' ;
9- import { data as elementData } from '@js/core/element_data' ;
108import type { dxElementWrapper } from '@js/core/renderer' ;
119import $ from '@js/core/renderer' ;
1210// @ts -expect-error
@@ -21,8 +19,9 @@ import { setOuterHeight, setOuterWidth } from '@js/core/utils/size';
2119import {
2220 isDeferred , isDefined , isPlainObject , isString ,
2321} from '@js/core/utils/type' ;
24- import CollectionWidget from '@js/ui/collection/ui.collection_widget.edit' ;
2522import { dateUtilsTs } from '@ts/core/utils/date' ;
23+ import type { SupportedKeys } from '@ts/core/widget/widget' ;
24+ import CollectionWidget from '@ts/ui/collection/collection_widget.edit' ;
2625
2726import { APPOINTMENT_SETTINGS_KEY } from '../constants' ;
2827import { APPOINTMENT_CONTENT_CLASSES , APPOINTMENT_DRAG_SOURCE_CLASS , APPOINTMENT_ITEM_CLASS } from '../m_classes' ;
@@ -47,12 +46,12 @@ import type {
4746import { AgendaAppointment } from './appointment/agenda_appointment' ;
4847import { Appointment } from './appointment/m_appointment' ;
4948import { createAgendaAppointmentLayout , createAppointmentLayout } from './m_appointment_layout' ;
49+ import { AppointmentsKeyboardNavigation } from './m_appointments_kbn' ;
5050import { getAppointmentDateRange } from './resizing/m_core' ;
5151import { countVisibleAppointments } from './utils/count_visible_appointments' ;
5252import { isNeedToAdd } from './utils/get_arrays_diff' ;
5353import { getViewModelDiff } from './utils/get_view_model_diff' ;
5454import { getAppointmentTakesSeveralDays , sortAppointmentsByStartDate } from './utils/m_utils' ;
55- import { getNextElement , getPrevElement } from './utils/sorted_index_utils' ;
5655
5756const COMPONENT_CLASS = 'dx-scheduler-scrollable-appointments' ;
5857
@@ -67,15 +66,12 @@ interface ViewModelDiff {
6766 needToRemove ?: true ;
6867}
6968
70- // @ts -expect-error
71- class SchedulerAppointments extends CollectionWidget {
69+ class SchedulerAppointments extends CollectionWidget < any > {
7270 // NOTE: The key of this array is `sortedIndex` of appointment rendered in Element
7371 renderedElementsBySortedIndex : dxElementWrapper [ ] = [ ] ;
7472
7573 _appointmentClickTimeout : any ;
7674
77- _$currentAppointment : any ;
78-
7975 _currentAppointmentSettings ?: AppointmentViewModelPlain ;
8076
8177 _preventSingleAppointmentClick : any ;
@@ -84,6 +80,14 @@ class SchedulerAppointments extends CollectionWidget {
8480
8581 _initialCoordinates : any ;
8682
83+ private _kbn ! : AppointmentsKeyboardNavigation ;
84+
85+ private _isResizing = false ;
86+
87+ public get isResizing ( ) : boolean {
88+ return this . _isResizing ;
89+ }
90+
8791 get isAgendaView ( ) {
8892 return this . invoke ( 'isCurrentViewAgenda' ) ;
8993 }
@@ -134,97 +138,35 @@ class SchedulerAppointments extends CollectionWidget {
134138 super . _dispose ( ) ;
135139 }
136140
137- _supportedKeys ( ) {
138- const parent = super . _supportedKeys ( ) ;
139-
140- const tabHandler = function ( e ) {
141- const navigatableItems = this . _getNavigatableItems ( ) ;
142- const focusedItem = navigatableItems . filter ( '.dx-state-focused' ) ;
143- let index = focusedItem . data ( APPOINTMENT_SETTINGS_KEY ) . sortedIndex ;
144- let $nextAppointment = e . shiftKey
145- ? getPrevElement ( index , this . renderedElementsBySortedIndex )
146- : getNextElement ( index , this . renderedElementsBySortedIndex ) ;
147- const lastIndex = navigatableItems . length - 1 ;
148-
149- if ( $nextAppointment || ( index > 0 && e . shiftKey ) || ( index < lastIndex && ! e . shiftKey ) ) {
150- e . preventDefault ( ) ;
151-
152- if ( ! $nextAppointment ) {
153- e . shiftKey ? index -- : index ++ ;
154- $nextAppointment = this . _getNavigatableItemByIndex ( index ) ;
155- }
156-
157- this . _resetTabIndex ( $nextAppointment ) ;
158- // @ts -expect-error
159- eventsEngine . trigger ( $nextAppointment , 'focus' ) ;
160- }
161- } ;
162-
163- const currentAppointment = this . _$currentAppointment ;
164-
165- return extend ( parent , {
166- escape : function ( ) {
167- if ( this . resizeOccur ) {
168- this . moveAppointmentBack ( ) ;
169- this . resizeOccur = false ;
170- currentAppointment . dxResizable ( 'instance' ) ?. _detachEventHandlers ( ) ;
171- currentAppointment . dxResizable ( 'instance' ) ?. _attachEventHandlers ( ) ;
172- currentAppointment . dxResizable ( 'instance' ) ?. _toggleResizingClass ( false ) ;
173- }
174- } . bind ( this ) ,
175- del : function ( e ) {
176- if ( this . option ( 'allowDelete' ) ) {
177- e . preventDefault ( ) ;
178- const data = this . _getItemData ( e . target ) ;
179- this . notifyObserver ( 'onDeleteButtonPress' , { data, target : e . target } ) ;
180- }
181- } . bind ( this ) ,
182- tab : tabHandler ,
183- } ) ;
184- }
185-
186- private _getNavigatableItemByIndex ( sortedIndex ) {
187- const appointments = this . _getNavigatableItems ( ) ;
188- return appointments . filter (
189- // @ts -expect-error
190- ( _ , $item ) => elementData ( $item , APPOINTMENT_SETTINGS_KEY ) . sortedIndex === sortedIndex ,
191- ) . eq ( 0 ) ;
192- }
141+ _supportedKeys ( ) : SupportedKeys {
142+ const parentValue = super . _supportedKeys ( ) ;
143+ const kbnValue = this . _kbn . getSupportedKeys ( ) ;
193144
194- private _getNavigatableItems ( ) : dxElementWrapper {
195- // @ts -expect-error
196- const appts = this . _itemElements ( ) . not ( '.dx-state-disabled' ) ;
197- // @ts -expect-error
198- const apptCollectors = this . $element ( ) . find ( '.dx-scheduler-appointment-collector' ) ;
199- return appts . add ( apptCollectors ) ;
145+ return extend ( parentValue , kbnValue ) as SupportedKeys ;
200146 }
201147
202- _resetTabIndex ( $appointment ) {
203- this . _focusTarget ( ) . attr ( 'tabIndex' , - 1 ) ;
204- $appointment . attr ( 'tabIndex' , this . option ( 'tabIndex' ) ) ;
148+ public getAppointmentSettings ( $item : dxElementWrapper ) : AppointmentViewModelPlain {
149+ return $item . data ( APPOINTMENT_SETTINGS_KEY ) as unknown as AppointmentViewModelPlain ;
205150 }
206151
207152 _moveFocus ( ) { }
208153
209154 _focusTarget ( ) {
210- return this . _getNavigatableItems ( ) ;
155+ return this . _kbn . getFocusableItems ( ) ;
211156 }
212157
213158 _renderFocusTarget ( ) {
214- const $appointment = this . _getNavigatableItemByIndex ( 0 ) ;
215-
216- this . _resetTabIndex ( $appointment ) ;
159+ const $item = this . _kbn . getFocusableItemBySortedIndex ( 0 ) ;
160+ this . _kbn . resetTabIndex ( $item ) ;
217161 }
218162
219163 _focusInHandler ( e ) {
220164 super . _focusInHandler ( e ) ;
221- this . _$currentAppointment = $ ( e . target ) ;
222- this . option ( 'focusedElement' , getPublicElement ( $ ( e . target ) ) ) ;
165+ this . _kbn . focusInHandler ( e ) ;
223166 }
224167
225168 _focusOutHandler ( e ) {
226- const $appointment = this . _getNavigatableItemByIndex ( 0 ) ;
227- this . option ( 'focusedElement' , getPublicElement ( $appointment ) ) ;
169+ this . _kbn . focusOutHandler ( ) ;
228170 super . _focusOutHandler ( e ) ;
229171 }
230172
@@ -291,7 +233,7 @@ class SchedulerAppointments extends CollectionWidget {
291233 this . _attachAppointmentsEvents ( ) ;
292234 break ;
293235 case 'focusedElement' :
294- this . _resetTabIndex ( $ ( args . value ) ) ;
236+ this . _kbn . resetTabIndex ( $ ( args . value ) ) ;
295237 super . _optionChanged ( args ) ;
296238 break ;
297239 case 'allowDelete' :
@@ -450,15 +392,9 @@ class SchedulerAppointments extends CollectionWidget {
450392 }
451393 }
452394
453- _clean ( ) {
454- super . _clean ( ) ;
455- delete this . _$currentAppointment ;
456- delete this . _initialSize ;
457- delete this . _initialCoordinates ;
458- }
459-
460395 _init ( ) {
461396 super . _init ( ) ;
397+ this . _kbn = new AppointmentsKeyboardNavigation ( this ) ;
462398 ( this as any ) . $element ( ) . addClass ( COMPONENT_CLASS ) ;
463399 this . _preventSingleAppointmentClick = false ;
464400 }
@@ -730,24 +666,29 @@ class SchedulerAppointments extends CollectionWidget {
730666 _resizableConfig ( appointmentData , itemSetting ) {
731667 return {
732668 area : this . _calculateResizableArea ( itemSetting , appointmentData ) ,
733- onResizeStart : function ( e ) {
734- this . resizeOccur = true ;
735- this . _$currentAppointment = $ ( e . element ) ;
669+ onResizeStart : ( e ) => {
670+ const $appointment = $ ( e . element ) ;
671+
672+ this . _isResizing = true ;
673+ this . _kbn . $focusedItem = $appointment ;
736674
737675 if ( this . invoke ( 'needRecalculateResizableArea' ) ) {
738- const updatedArea = this . _calculateResizableArea ( this . _$currentAppointment . data ( APPOINTMENT_SETTINGS_KEY ) , this . _$currentAppointment . data ( 'dxItemData' ) ) ;
676+ const updatedArea = this . _calculateResizableArea (
677+ this . getAppointmentSettings ( $appointment ) ,
678+ $appointment . data ( 'dxItemData' ) ,
679+ ) ;
739680
740681 e . component . option ( 'area' , updatedArea ) ;
741682 e . component . _renderDragOffsets ( e . event ) ;
742683 }
743684
744685 this . _initialSize = { width : e . width , height : e . height } ;
745- this . _initialCoordinates = locate ( this . _$currentAppointment ) ;
746- } . bind ( this ) ,
747- onResizeEnd : function ( e ) {
748- this . resizeOccur = false ;
686+ this . _initialCoordinates = locate ( $appointment ) ;
687+ } ,
688+ onResizeEnd : ( e ) => {
689+ this . _isResizing = false ;
749690 this . _resizeEndHandler ( e ) ;
750- } . bind ( this ) ,
691+ } ,
751692 } ;
752693 }
753694
@@ -1160,11 +1101,13 @@ class SchedulerAppointments extends CollectionWidget {
11601101 return obj ;
11611102 }
11621103
1163- moveAppointmentBack ( dragEvent ) {
1164- const $appointment = this . _$currentAppointment ;
1104+ moveAppointmentBack ( dragEvent ? ) {
1105+ const $appointment = this . _kbn . $focusedItem ;
11651106 const size = this . _initialSize ;
11661107 const coords = this . _initialCoordinates ;
11671108
1109+ this . _isResizing = false ;
1110+
11681111 if ( dragEvent ) {
11691112 this . _removeDragSourceClassFromDraggedAppointment ( ) ;
11701113
@@ -1189,12 +1132,7 @@ class SchedulerAppointments extends CollectionWidget {
11891132 }
11901133
11911134 focus ( ) {
1192- if ( this . _$currentAppointment ) {
1193- const focusedElement = getPublicElement ( this . _$currentAppointment ) ;
1194-
1195- this . option ( 'focusedElement' , focusedElement ) ;
1196- ( eventsEngine as any ) . trigger ( focusedElement , 'focus' ) ;
1197- }
1135+ this . _kbn . focus ( ) ;
11981136 }
11991137
12001138 splitAppointmentByDay ( appointment ) {
0 commit comments