Skip to content
Draft
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
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import type {
AppointmentCollectorViewModel,
AppointmentItemViewModel,
AppointmentViewModelPlain,
SortedEntity,
} from '../view_model/types';
import { AgendaAppointment } from './appointment/agenda_appointment';
import { Appointment } from './appointment/m_appointment';
Expand All @@ -68,7 +69,7 @@ interface ViewModelDiff {

class SchedulerAppointments extends CollectionWidget<any> {
// NOTE: The key of this array is `sortedIndex` of appointment rendered in Element
renderedElementsBySortedIndex: dxElementWrapper[] = [];
$itemBySortedIndex: dxElementWrapper[] = [];

_appointmentClickTimeout: any;

Expand All @@ -82,17 +83,19 @@ class SchedulerAppointments extends CollectionWidget<any> {

private _kbn!: AppointmentsKeyboardNavigation;

private _focusedItemIndexBeforeRender!: number;

private _isResizing = false;

public get isResizing(): boolean {
return this._isResizing;
}

get isAgendaView() {
get isAgendaView(): boolean {
return this.invoke('isCurrentViewAgenda');
}

get isVirtualScrolling() {
get isVirtualScrolling(): boolean {
return this.invoke('isVirtualScrolling');
}

Expand All @@ -104,6 +107,10 @@ class SchedulerAppointments extends CollectionWidget<any> {
return this.option('dataAccessors') as AppointmentDataAccessor;
}

get sortedItems(): SortedEntity[] {
return this.option('getSortedAppointments')() as SortedEntity[];
}

getResourceManager(): ResourceManager {
return this.option('getResourceManager')();
}
Expand Down Expand Up @@ -138,7 +145,11 @@ class SchedulerAppointments extends CollectionWidget<any> {
const parentValue = super._supportedKeys();
const kbnValue = this._kbn.getSupportedKeys();

return extend(parentValue, kbnValue) as SupportedKeys;
return {
enter: parentValue.enter,
space: parentValue.space,
...kbnValue,
};
}

public getAppointmentSettings($item: dxElementWrapper): AppointmentViewModelPlain {
Expand All @@ -152,8 +163,26 @@ class SchedulerAppointments extends CollectionWidget<any> {
}

_renderFocusTarget() {
const $item = this._kbn.getFocusableItemBySortedIndex(0);
this._kbn.resetTabIndex($item);
this._kbn.resetTabIndex();
}

_cleanFocusState(): void {
this._focusedItemIndexBeforeRender = this._kbn.isNavigating
? this._kbn.focusedItemSortIndex
: -1;

super._cleanFocusState();
}

_renderFocusState(): void {
super._renderFocusState();

if (this._focusedItemIndexBeforeRender !== -1) {
this._kbn.focusedItemSortIndex = this._focusedItemIndexBeforeRender;
this._kbn.isNavigating = false;
this._kbn.focus();
this._focusedItemIndexBeforeRender = -1;
}
}

_focusInHandler(e) {
Expand All @@ -162,7 +191,7 @@ class SchedulerAppointments extends CollectionWidget<any> {
}

_focusOutHandler(e) {
this._kbn.focusOutHandler();
this._kbn.focusOutHandler(e);
super._focusOutHandler(e);
}

Expand Down Expand Up @@ -192,7 +221,7 @@ class SchedulerAppointments extends CollectionWidget<any> {
value: AppointmentViewModelPlain[] = [],
): ViewModelDiff[] {
const elementsInRenderOrder = previousValue
.map(({ sortedIndex }) => this.renderedElementsBySortedIndex[sortedIndex]);
.map(({ sortedIndex }) => this.$itemBySortedIndex[sortedIndex]);
const diff = getViewModelDiff(previousValue, value, this.appointmentDataSource);
diff
.filter((item) => !isNeedToAdd(item))
Expand All @@ -206,7 +235,7 @@ class SchedulerAppointments extends CollectionWidget<any> {
_optionChanged(args) {
switch (args.name) {
case 'items':
(this as any)._cleanFocusState();
this._cleanFocusState();

if (this.isAgendaView) {
this.forceRepaintAllAppointments(args.value || []);
Expand All @@ -225,12 +254,11 @@ class SchedulerAppointments extends CollectionWidget<any> {
case 'allowResize':
case 'allowDelete':
case 'allowAllDayResize':
(this as any)._cleanFocusState();
this._cleanFocusState();
this.forceRepaintAllAppointments(this.option('items') || []);
this._attachAppointmentsEvents();
break;
case 'focusedElement':
this._kbn.resetTabIndex($(args.value));
super._optionChanged(args);
break;
case 'focusStateEnabled':
Expand All @@ -251,7 +279,7 @@ class SchedulerAppointments extends CollectionWidget<any> {
}

protected forceRepaintAllAppointments(items: AppointmentViewModelPlain[]): void {
this.renderedElementsBySortedIndex = [];
this.$itemBySortedIndex = [];
this._renderByFragments(($commonFragment, $allDayFragment) => {
this._getAppointmentContainer(true).html('');
this._getAppointmentContainer(false).html('');
Expand All @@ -269,10 +297,12 @@ class SchedulerAppointments extends CollectionWidget<any> {
}

protected repaintAppointments(diff: ViewModelDiff[]): void {
this.renderedElementsBySortedIndex = [];
this.$itemBySortedIndex = [];

this._renderByFragments(($commonFragment, $allDayFragment) => {
const isRepaintAll = this.isAgendaView
|| !diff.some((item) => item.needToAdd === undefined && item.needToRemove === undefined);
const isRepaintAll = diff.every(
(item) => Boolean(item.needToAdd ?? item.needToRemove),
);

if (isRepaintAll) {
this._getAppointmentContainer(true).html('');
Expand Down Expand Up @@ -303,7 +333,7 @@ class SchedulerAppointments extends CollectionWidget<any> {

if (item.element) {
item.element.data(APPOINTMENT_SETTINGS_KEY, item.item);
this.renderedElementsBySortedIndex[item.item.sortedIndex] = item.element;
this.$itemBySortedIndex[item.item.sortedIndex] = item.element;
}
});
});
Expand Down Expand Up @@ -334,14 +364,14 @@ class SchedulerAppointments extends CollectionWidget<any> {
}

_attachAppointmentsEvents() {
(this as any)._attachClickEvent();
(this as any)._attachHoldEvent();
(this as any)._attachContextMenuEvent();
(this as any)._attachAppointmentDblClick();
this._attachClickEvent();
this._attachHoldEvent();
this._attachContextMenuEvent();
this._attachAppointmentDblClick();

(this as any)._renderFocusState();
(this as any)._attachFeedbackEvents();
(this as any)._attachHoverEvents();
this._renderFocusState();
this._attachFeedbackEvents();
this._attachHoverEvents();
}

_clearDropDownItemsElements() {
Expand Down Expand Up @@ -390,7 +420,8 @@ class SchedulerAppointments extends CollectionWidget<any> {
_init() {
super._init();
this._kbn = new AppointmentsKeyboardNavigation(this);
(this as any).$element().addClass(COMPONENT_CLASS);
this._focusedItemIndexBeforeRender = -1;
this.$element().addClass(COMPONENT_CLASS);
this._preventSingleAppointmentClick = false;
}

Expand Down Expand Up @@ -519,12 +550,13 @@ class SchedulerAppointments extends CollectionWidget<any> {
const $item = super._renderItem(index, item.itemData, container);

$item.data(APPOINTMENT_SETTINGS_KEY, item);

if (item.sortedIndex !== -1) {
// NOTE: fallback for integration testing
if (!this.renderedElementsBySortedIndex) {
this.renderedElementsBySortedIndex = [];
if (!this.$itemBySortedIndex) {
this.$itemBySortedIndex = [];
}
this.renderedElementsBySortedIndex[item.sortedIndex] = $item;
this.$itemBySortedIndex[item.sortedIndex] = $item;
}

return $item;
Expand Down Expand Up @@ -673,7 +705,7 @@ class SchedulerAppointments extends CollectionWidget<any> {
const $appointment = $(e.element);

this._isResizing = true;
this._kbn.$focusedItem = $appointment;
this._kbn.focus($appointment);

if (this.invoke('needRecalculateResizableArea')) {
const updatedArea = this._calculateResizableArea(
Expand Down Expand Up @@ -983,13 +1015,13 @@ class SchedulerAppointments extends CollectionWidget<any> {
allowDrag: this.option('allowDrag'),
isCompact: appointment.isCompact,
});
this.renderedElementsBySortedIndex[appointment.sortedIndex] = $item;
this.$itemBySortedIndex[appointment.sortedIndex] = $item;

return $item;
}

moveAppointmentBack(dragEvent?) {
const $appointment = this._kbn.$focusedItem;
const $appointment = this._kbn.$focusTarget();
const size = this._initialSize;
const coords = this._initialCoordinates;

Expand All @@ -1005,7 +1037,7 @@ class SchedulerAppointments extends CollectionWidget<any> {
}
}

if ($appointment && !dragEvent) {
if ($appointment.get(0) && !dragEvent) {
if (coords) {
move($appointment, coords);
delete this._initialSize;
Expand Down
Loading
Loading