Skip to content

Commit 34fe5bc

Browse files
authored
Scheduler refactor (#29598)
Co-authored-by: Vladimir Bushmanov <[email protected]>
1 parent 74d4449 commit 34fe5bc

File tree

61 files changed

+407
-474
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+407
-474
lines changed

packages/devextreme/js/__internal/scheduler/appointments/data_provider/m_appointment_data_provider.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import config from '@js/core/config';
22
import { combineRemoteFilter } from '@ts/scheduler/r1/filterting/index';
3+
import type { AppointmentDataItem, SafeAppointment } from '@ts/scheduler/types';
34
import type { AppointmentDataAccessor } from '@ts/scheduler/utils';
45

56
import { AppointmentDataSource } from './m_appointment_data_source';
@@ -101,7 +102,7 @@ export class AppointmentDataProvider {
101102
}
102103

103104
// Filter mapping
104-
filter(preparedItems) {
105+
filter(preparedItems: AppointmentDataItem[]): SafeAppointment[] {
105106
return this.getFilterStrategy().filter(preparedItems);
106107
}
107108

packages/devextreme/js/__internal/scheduler/appointments/data_provider/m_appointment_filter.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@ import dateUtils from '@js/core/utils/date';
44
import { map } from '@js/core/utils/iterator';
55
import { isDefined, isFunction } from '@js/core/utils/type';
66
import { dateUtilsTs } from '@ts/core/utils/date';
7-
import type { AppointmentDataItem } from '@ts/scheduler/r1/types';
87
import {
98
getDatesWithoutTime, hasResourceValue, isAppointmentTakesAllDay, isTimelineView,
109
} from '@ts/scheduler/r1/utils/index';
10+
import type { AppointmentDataItem, SafeAppointment } from '@ts/scheduler/types';
1111
import type { AppointmentDataAccessor } from '@ts/scheduler/utils';
12+
import type ViewDataProvider from '@ts/scheduler/workspaces/view_model/m_view_data_provider';
1213

1314
import { createAppointmentAdapter } from '../../m_appointment_adapter';
1415
import { getRecurrenceProcessor } from '../../m_recurrence';
@@ -60,7 +61,7 @@ export class AppointmentFilterBaseStrategy {
6061

6162
get groupCount() { return this._resolveOption('groupCount'); }
6263

63-
get viewDataProvider() { return this._resolveOption('viewDataProvider'); }
64+
get viewDataProvider(): ViewDataProvider { return this._resolveOption('viewDataProvider'); }
6465

6566
get allDayPanelMode() { return this._resolveOption('allDayPanelMode'); }
6667

@@ -71,7 +72,7 @@ export class AppointmentFilterBaseStrategy {
7172
: result;
7273
}
7374

74-
filter(preparedItems: AppointmentDataItem[]) {
75+
filter(preparedItems: AppointmentDataItem[]): SafeAppointment[] {
7576
const [min, max] = this.dateRange;
7677
const { viewOffset } = this.options;
7778
const allDay = !this.showAllDayPanel && this.supportAllDayRow
@@ -304,12 +305,12 @@ export class AppointmentFilterBaseStrategy {
304305
return result;
305306
}
306307

307-
filterLoadedAppointments(filterOptions, preparedItems: AppointmentDataItem[]) {
308+
filterLoadedAppointments(filterOptions, preparedItems: AppointmentDataItem[]): SafeAppointment[] {
308309
const filteredItems = this.filterPreparedItems(filterOptions, preparedItems);
309310
return filteredItems.map(({ rawAppointment }) => rawAppointment);
310311
}
311312

312-
filterPreparedItems(filterOptions, preparedItems: AppointmentDataItem[]) {
313+
filterPreparedItems(filterOptions, preparedItems: AppointmentDataItem[]): AppointmentDataItem[] {
313314
const combinedFilter = this._createCombinedFilter(filterOptions);
314315

315316
// @ts-expect-error
@@ -319,7 +320,7 @@ export class AppointmentFilterBaseStrategy {
319320
.toArray();
320321
}
321322

322-
filterAllDayAppointments(preparedItems: AppointmentDataItem[]) {
323+
filterAllDayAppointments(preparedItems: AppointmentDataItem[]): SafeAppointment[] {
323324
const combinedFilter = this._createAllDayAppointmentFilter();
324325
// @ts-expect-error
325326
return query(preparedItems)

packages/devextreme/js/__internal/scheduler/appointments/data_provider/m_appointment_filter_virtual.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import query from '@js/common/data/query';
22
import dateUtils from '@js/core/utils/date';
33
import { dateUtilsTs } from '@ts/core/utils/date';
4-
import type { AppointmentDataItem } from '@ts/scheduler/r1/types';
54
import { isDateAndTimeView, isTimelineView } from '@ts/scheduler/r1/utils/index';
5+
import type { AppointmentDataItem, SafeAppointment } from '@ts/scheduler/types';
66

77
import {
88
getResourcesDataByGroups,
@@ -18,7 +18,7 @@ export class AppointmentFilterVirtualStrategy extends AppointmentFilterBaseStrat
1818

1919
get resources() { return this.options.resources; }
2020

21-
filter(preparedItems: AppointmentDataItem[]) {
21+
filter(preparedItems: AppointmentDataItem[]): SafeAppointment[] {
2222
const { viewOffset } = this.options;
2323
const hourMs = toMs('hour');
2424
const isCalculateStartAndEndDayHour = isDateAndTimeView(this.viewType);
@@ -78,7 +78,10 @@ export class AppointmentFilterVirtualStrategy extends AppointmentFilterBaseStrat
7878
}, preparedItems);
7979
}
8080

81-
filterPreparedItems({ filterOptions, groupCount }, preparedItems: AppointmentDataItem[]) {
81+
filterPreparedItems(
82+
{ filterOptions, groupCount },
83+
preparedItems: AppointmentDataItem[],
84+
): AppointmentDataItem[] {
8285
const combinedFilters: any = [];
8386

8487
let itemsToFilter = preparedItems;
@@ -110,7 +113,7 @@ export class AppointmentFilterVirtualStrategy extends AppointmentFilterBaseStrat
110113
.toArray();
111114
}
112115

113-
hasAllDayAppointments(filteredItems, preparedItems: AppointmentDataItem[]) {
116+
hasAllDayAppointments(filteredItems, preparedItems: AppointmentDataItem[]): boolean {
114117
return this.filterAllDayAppointments(preparedItems).length > 0;
115118
}
116119

packages/devextreme/js/__internal/scheduler/appointments/data_provider/m_utils.test.ts

Lines changed: 0 additions & 44 deletions
This file was deleted.

packages/devextreme/js/__internal/scheduler/appointments/data_provider/m_utils.ts

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,6 @@ export const compareDateWithEndDayHour = (options) => {
6868

6969
export const getAppointmentTakesSeveralDays = (adapter) => !dateUtils.sameDate(adapter.startDate, adapter.endDate);
7070

71-
// eslint-disable-next-line @typescript-eslint/naming-convention
72-
export const _isEndDateWrong = (startDate, endDate) => !endDate || isNaN(endDate.getTime()) || startDate.getTime() > endDate.getTime();
73-
7471
// eslint-disable-next-line @typescript-eslint/naming-convention
7572
export const _appointmentPartInInterval = (startDate, endDate, startDayHour, endDayHour) => {
7673
const apptStartDayHour = startDate.getHours();
@@ -124,29 +121,6 @@ export const _convertRecurrenceException = (exceptionString, startDate, timeZone
124121
return exceptionString;
125122
};
126123

127-
export const replaceWrongEndDate = (
128-
rawAppointment,
129-
startDate,
130-
endDate,
131-
appointmentDuration,
132-
dataAccessors: AppointmentDataAccessor,
133-
) => {
134-
const calculateAppointmentEndDate = (isAllDay, startDate) => {
135-
if (isAllDay) {
136-
return dateUtils.setToDayEnd(new Date(startDate));
137-
}
138-
139-
return new Date(startDate.getTime() + appointmentDuration * toMs('minute'));
140-
};
141-
142-
if (_isEndDateWrong(startDate, endDate)) {
143-
const isAllDay = Boolean(dataAccessors.get('allDay', rawAppointment));
144-
145-
const calculatedEndDate = calculateAppointmentEndDate(isAllDay, startDate);
146-
dataAccessors.set('endDate', rawAppointment, calculatedEndDate);
147-
}
148-
};
149-
150124
export const sortAppointmentsByStartDate = (
151125
appointments,
152126
dataAccessors: AppointmentDataAccessor,

packages/devextreme/js/__internal/scheduler/appointments/m_appointment_collection.ts

Lines changed: 37 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,13 @@ import {
2525
import CollectionWidget from '@js/ui/collection/ui.collection_widget.edit';
2626
import { dateUtilsTs } from '@ts/core/utils/date';
2727

28+
import { APPOINTMENT_SETTINGS_KEY } from '../constants';
2829
import { createAppointmentAdapter } from '../m_appointment_adapter';
2930
import { APPOINTMENT_CONTENT_CLASSES, APPOINTMENT_DRAG_SOURCE_CLASS, APPOINTMENT_ITEM_CLASS } from '../m_classes';
30-
import { APPOINTMENT_SETTINGS_KEY } from '../m_constants';
3131
import { getRecurrenceProcessor } from '../m_recurrence';
3232
import timeZoneUtils from '../m_utils_time_zone';
3333
import { getPathToLeaf } from '../resources/m_utils';
34+
import type { AppointmentViewModel } from '../types';
3435
import type { AppointmentDataAccessor } from '../utils';
3536
import { getAppointmentTakesSeveralDays, sortAppointmentsByStartDate } from './data_provider/m_utils';
3637
import { AgendaAppointment, Appointment } from './m_appointment';
@@ -42,6 +43,10 @@ const COMPONENT_CLASS = 'dx-scheduler-scrollable-appointments';
4243
const DBLCLICK_EVENT_NAME = addNamespace(dblclickEvent, 'dxSchedulerAppointment');
4344

4445
const toMs = dateUtils.dateToMilliseconds;
46+
const isAllDayAppointment = (
47+
appointment: AppointmentViewModel,
48+
): boolean => Boolean(appointment.settings[0]?.allDay);
49+
4550
// @ts-expect-error
4651
class SchedulerAppointments extends CollectionWidget {
4752
_virtualAppointments: any;
@@ -174,7 +179,7 @@ class SchedulerAppointments extends CollectionWidget {
174179
_moveFocus() {}
175180

176181
_focusTarget() {
177-
return (this as any)._getNavigatableItems();
182+
return this._getNavigatableItems();
178183
}
179184

180185
_renderFocusTarget() {
@@ -254,67 +259,48 @@ class SchedulerAppointments extends CollectionWidget {
254259
}
255260
}
256261

257-
_isAllDayAppointment(appointment) {
258-
return appointment.settings.length && appointment.settings[0].allDay || false;
259-
}
260-
261-
_isRepaintAppointment(appointment) {
262-
return !isDefined(appointment.needRepaint) || appointment.needRepaint === true;
263-
}
264-
265-
_isRepaintAll(appointments) {
266-
if (this.isAgendaView) {
267-
return true;
268-
}
269-
for (let i = 0; i < appointments.length; i++) {
270-
if (!this._isRepaintAppointment(appointments[i])) {
271-
return false;
272-
}
273-
}
274-
return true;
262+
_isRepaintAll(appointments: AppointmentViewModel[]): boolean {
263+
return this.isAgendaView || appointments.every((item) => item.needRepaint);
275264
}
276265

277-
_applyFragment(fragment, allDay) {
266+
_applyFragment(fragment: dxElementWrapper, allDay: boolean): void {
278267
if (fragment.children().length > 0) {
279268
this._getAppointmentContainer(allDay).append(fragment);
280269
}
281270
}
282271

283-
_onEachAppointment(appointment, index, container, isRepaintAll) {
284-
const repaintAppointment = () => {
285-
appointment.needRepaint = false;
286-
this._clearItem(appointment);
287-
this._renderItem(index, appointment, container);
288-
};
289-
290-
if (appointment?.needRemove === true) {
291-
this._clearItem(appointment);
292-
} else if (isRepaintAll || this._isRepaintAppointment(appointment)) {
293-
repaintAppointment();
294-
}
295-
}
296-
297-
_repaintAppointments(appointments) {
272+
_repaintAppointments(appointments: AppointmentViewModel[]): void {
298273
this._renderByFragments(($commonFragment, $allDayFragment) => {
299274
const isRepaintAll = this._isRepaintAll(appointments);
300275

301276
if (isRepaintAll) {
302277
this._getAppointmentContainer(true).html('');
303278
this._getAppointmentContainer(false).html('');
304279
}
305-
306-
!appointments.length && this._cleanItemContainer();
280+
if (!appointments.length) {
281+
this._cleanItemContainer();
282+
}
307283

308284
appointments.forEach((appointment, index) => {
309-
const container = this._isAllDayAppointment(appointment)
285+
const container = isAllDayAppointment(appointment)
310286
? $allDayFragment
311287
: $commonFragment;
312-
this._onEachAppointment(appointment, index, container, isRepaintAll);
288+
289+
if (appointment.needRemove) {
290+
this._clearItem(appointment);
291+
} else if (isRepaintAll || appointment.needRepaint) {
292+
appointment.needRepaint = false;
293+
this._clearItem(appointment);
294+
this._renderItem(index, appointment, container);
295+
}
313296
});
314297
});
315298
}
316299

317-
_renderByFragments(renderFunction) {
300+
_renderByFragments(renderFunction: (
301+
$commonFragment: dxElementWrapper,
302+
$allDayFragment: dxElementWrapper,
303+
) => void): void {
318304
if (this.isVirtualScrolling) {
319305
const $commonFragment = $(domAdapter.createDocumentFragment() as any);
320306
const $allDayFragment = $(domAdapter.createDocumentFragment() as any);
@@ -346,7 +332,7 @@ class SchedulerAppointments extends CollectionWidget {
346332
(this as any)._attachHoverEvents();
347333
}
348334

349-
_clearItem(item) {
335+
_clearItem(item: AppointmentViewModel): void {
350336
const $items = this._findItemElementByItem(item.itemData);
351337
if (!$items.length) {
352338
return;
@@ -521,9 +507,13 @@ class SchedulerAppointments extends CollectionWidget {
521507
this.notifyObserver('showEditAppointmentPopup', { data: appointmentData, target: $targetAppointment });
522508
}
523509

524-
_renderItem(index, item, container) {
510+
_renderItem(
511+
index: number,
512+
item: AppointmentViewModel,
513+
container: dxElementWrapper,
514+
): dxElementWrapper[] {
525515
const { itemData } = item;
526-
const $items: any = [];
516+
const $items: dxElementWrapper[] = [];
527517

528518
for (let i = 0; i < item.settings.length; i++) {
529519
const setting = item.settings[i];
@@ -557,15 +547,11 @@ class SchedulerAppointments extends CollectionWidget {
557547
});
558548
}
559549

560-
_getAppointmentContainer(allDay) {
550+
_getAppointmentContainer(allDay: boolean): dxElementWrapper {
561551
const $allDayContainer = this.option('allDayContainer');
562-
let $container = (this as any).itemsContainer().not($allDayContainer);
563-
564-
if (allDay && $allDayContainer) {
565-
$container = $allDayContainer;
566-
}
552+
const $container = (this as any).itemsContainer().not($allDayContainer);
567553

568-
return $container;
554+
return allDay && $allDayContainer ? $allDayContainer : $container;
569555
}
570556

571557
_postprocessRenderItem(args) {

0 commit comments

Comments
 (0)