Skip to content

Commit dc40485

Browse files
authored
Scheduler refactoring (DevExpress#29599)
Co-authored-by: Vladimir Bushmanov <[email protected]>
1 parent cabf095 commit dc40485

File tree

61 files changed

+406
-472
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

+406
-472
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
@@ -5,11 +5,12 @@ import { map } from '@js/core/utils/iterator';
55
import { isDefined, isFunction } from '@js/core/utils/type';
66
import query from '@js/data/query';
77
import { dateUtilsTs } from '@ts/core/utils/date';
8-
import type { AppointmentDataItem } from '@ts/scheduler/r1/types';
98
import {
109
getDatesWithoutTime, hasResourceValue, isAppointmentTakesAllDay, isTimelineView,
1110
} from '@ts/scheduler/r1/utils/index';
11+
import type { AppointmentDataItem, SafeAppointment } from '@ts/scheduler/types';
1212
import type { AppointmentDataAccessor } from '@ts/scheduler/utils';
13+
import type ViewDataProvider from '@ts/scheduler/workspaces/view_model/m_view_data_provider';
1314

1415
import { createAppointmentAdapter } from '../../m_appointment_adapter';
1516
import { getRecurrenceProcessor } from '../../m_recurrence';
@@ -61,7 +62,7 @@ export class AppointmentFilterBaseStrategy {
6162

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

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

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

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

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

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

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

316317
return query(preparedItems)
317318
.filter(combinedFilter)
318319
.toArray();
319320
}
320321

321-
filterAllDayAppointments(preparedItems: AppointmentDataItem[]) {
322+
filterAllDayAppointments(preparedItems: AppointmentDataItem[]): SafeAppointment[] {
322323
const combinedFilter = this._createAllDayAppointmentFilter();
323324
return query(preparedItems)
324325
.filter(combinedFilter)

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 dateUtils from '@js/core/utils/date';
22
import query from '@js/data/query';
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;
@@ -108,7 +111,7 @@ export class AppointmentFilterVirtualStrategy extends AppointmentFilterBaseStrat
108111
.toArray();
109112
}
110113

111-
hasAllDayAppointments(filteredItems, preparedItems: AppointmentDataItem[]) {
114+
hasAllDayAppointments(filteredItems, preparedItems: AppointmentDataItem[]): boolean {
112115
return this.filterAllDayAppointments(preparedItems).length > 0;
113116
}
114117

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

Lines changed: 0 additions & 43 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: 36 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,12 @@ import { addNamespace, isFakeClickEvent } from '@js/events/utils/index';
2323
import CollectionWidget from '@js/ui/collection/ui.collection_widget.edit';
2424
import { dateUtilsTs } from '@ts/core/utils/date';
2525

26+
import { APPOINTMENT_SETTINGS_KEY } from '../constants';
2627
import { createAppointmentAdapter } from '../m_appointment_adapter';
2728
import { APPOINTMENT_CONTENT_CLASSES, APPOINTMENT_DRAG_SOURCE_CLASS, APPOINTMENT_ITEM_CLASS } from '../m_classes';
28-
import { APPOINTMENT_SETTINGS_KEY } from '../m_constants';
2929
import { getRecurrenceProcessor } from '../m_recurrence';
3030
import timeZoneUtils from '../m_utils_time_zone';
31+
import type { AppointmentViewModel } from '../types';
3132
import type { AppointmentDataAccessor } from '../utils';
3233
import { getAppointmentTakesSeveralDays, sortAppointmentsByStartDate } from './data_provider/m_utils';
3334
import { AgendaAppointment, Appointment } from './m_appointment';
@@ -40,6 +41,10 @@ const DBLCLICK_EVENT_NAME = addNamespace(dblclickEvent, 'dxSchedulerAppointment'
4041

4142
const toMs = dateUtils.dateToMilliseconds;
4243

44+
const isAllDayAppointment = (
45+
appointment: AppointmentViewModel,
46+
): boolean => Boolean(appointment.settings[0]?.allDay);
47+
4348
class SchedulerAppointments extends CollectionWidget {
4449
_virtualAppointments: any;
4550

@@ -245,67 +250,48 @@ class SchedulerAppointments extends CollectionWidget {
245250
}
246251
}
247252

248-
_isAllDayAppointment(appointment) {
249-
return appointment.settings.length && appointment.settings[0].allDay || false;
250-
}
251-
252-
_isRepaintAppointment(appointment) {
253-
return !isDefined(appointment.needRepaint) || appointment.needRepaint === true;
254-
}
255-
256-
_isRepaintAll(appointments) {
257-
if (this.isAgendaView) {
258-
return true;
259-
}
260-
for (let i = 0; i < appointments.length; i++) {
261-
if (!this._isRepaintAppointment(appointments[i])) {
262-
return false;
263-
}
264-
}
265-
return true;
253+
_isRepaintAll(appointments: AppointmentViewModel[]): boolean {
254+
return this.isAgendaView || appointments.every((item) => item.needRepaint);
266255
}
267256

268-
_applyFragment(fragment, allDay) {
257+
_applyFragment(fragment, allDay: boolean): void {
269258
if (fragment.children().length > 0) {
270259
this._getAppointmentContainer(allDay).append(fragment);
271260
}
272261
}
273262

274-
_onEachAppointment(appointment, index, container, isRepaintAll) {
275-
const repaintAppointment = () => {
276-
appointment.needRepaint = false;
277-
this._clearItem(appointment);
278-
this._renderItem(index, appointment, container);
279-
};
280-
281-
if (appointment?.needRemove === true) {
282-
this._clearItem(appointment);
283-
} else if (isRepaintAll || this._isRepaintAppointment(appointment)) {
284-
repaintAppointment();
285-
}
286-
}
287-
288-
_repaintAppointments(appointments) {
263+
_repaintAppointments(appointments: AppointmentViewModel[]): void {
289264
this._renderByFragments(($commonFragment, $allDayFragment) => {
290265
const isRepaintAll = this._isRepaintAll(appointments);
291266

292267
if (isRepaintAll) {
293268
this._getAppointmentContainer(true).html('');
294269
this._getAppointmentContainer(false).html('');
295270
}
296-
297-
!appointments.length && this._cleanItemContainer();
271+
if (!appointments.length) {
272+
this._cleanItemContainer();
273+
}
298274

299275
appointments.forEach((appointment, index) => {
300-
const container = this._isAllDayAppointment(appointment)
276+
const container = isAllDayAppointment(appointment)
301277
? $allDayFragment
302278
: $commonFragment;
303-
this._onEachAppointment(appointment, index, container, isRepaintAll);
279+
280+
if (appointment.needRemove) {
281+
this._clearItem(appointment);
282+
} else if (isRepaintAll || appointment.needRepaint) {
283+
appointment.needRepaint = false;
284+
this._clearItem(appointment);
285+
this._renderItem(index, appointment, container);
286+
}
304287
});
305288
});
306289
}
307290

308-
_renderByFragments(renderFunction) {
291+
_renderByFragments(renderFunction: (
292+
$commonFragment,
293+
$allDayFragment,
294+
) => void): void {
309295
if (this.isVirtualScrolling) {
310296
const $commonFragment = $(domAdapter.createDocumentFragment() as any);
311297
const $allDayFragment = $(domAdapter.createDocumentFragment() as any);
@@ -333,7 +319,7 @@ class SchedulerAppointments extends CollectionWidget {
333319
(this as any)._attachHoverEvents();
334320
}
335321

336-
_clearItem(item) {
322+
_clearItem(item: AppointmentViewModel): void {
337323
const $items = this._findItemElementByItem(item.itemData);
338324
if (!$items.length) {
339325
return;
@@ -504,9 +490,13 @@ class SchedulerAppointments extends CollectionWidget {
504490
this.notifyObserver('showEditAppointmentPopup', { data: appointmentData, target: $targetAppointment });
505491
}
506492

507-
_renderItem(index, item, container) {
493+
_renderItem(
494+
index: number,
495+
item: AppointmentViewModel,
496+
container,
497+
) {
508498
const { itemData } = item;
509-
const $items: any = [];
499+
const $items: any[] = [];
510500

511501
for (let i = 0; i < item.settings.length; i++) {
512502
const setting = item.settings[i];
@@ -540,15 +530,11 @@ class SchedulerAppointments extends CollectionWidget {
540530
});
541531
}
542532

543-
_getAppointmentContainer(allDay) {
533+
_getAppointmentContainer(allDay: boolean) {
544534
const $allDayContainer = this.option('allDayContainer');
545-
let $container = (this as any).itemsContainer().not($allDayContainer);
546-
547-
if (allDay && $allDayContainer) {
548-
$container = $allDayContainer;
549-
}
535+
const $container = (this as any).itemsContainer().not($allDayContainer);
550536

551-
return $container;
537+
return allDay && $allDayContainer ? $allDayContainer : $container;
552538
}
553539

554540
_postprocessRenderItem(args) {

0 commit comments

Comments
 (0)