Skip to content

Commit 3a6985c

Browse files
authored
refactor data accessor (DevExpress#29515)
Co-authored-by: Vladimir Bushmanov <vladimir.bushmanov@devexpress.com>
1 parent 922bdc1 commit 3a6985c

43 files changed

Lines changed: 746 additions & 1078 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { AppointmentDataAccessor, type IFieldExpr } from '../utils';
2+
3+
export const mockFieldExpressions: IFieldExpr = {
4+
startDateExpr: 'startDate',
5+
endDateExpr: 'endDate',
6+
startDateTimeZoneExpr: 'startDateTimeZone',
7+
endDateTimeZoneExpr: 'endDateTimeZone',
8+
allDayExpr: 'allDay',
9+
textExpr: 'text',
10+
descriptionExpr: 'description',
11+
recurrenceRuleExpr: 'recurrenceRule',
12+
recurrenceExceptionExpr: 'recurrenceException',
13+
disabledExpr: 'disabled',
14+
visibleExpr: 'visible',
15+
};
16+
17+
export const mockAppointmentDataAccessor = new AppointmentDataAccessor(mockFieldExpressions, true);

packages/devextreme/js/__internal/scheduler/appointment_popup/m_form.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import { extend } from '@js/core/utils/extend';
1414
import type AbstractStore from '@js/data/abstract_store';
1515
import Form from '@js/ui/form';
1616
import { current, isFluent } from '@js/ui/themes';
17-
import { ExpressionUtils } from '@ts/scheduler/m_expression_utils';
1817

1918
import { createAppointmentAdapter } from '../m_appointment_adapter';
2019
import type { TimezoneLabel } from '../m_utils_time_zone';
@@ -102,7 +101,7 @@ export class AppointmentForm {
102101
const dataAccessors = this.scheduler.getDataAccessors();
103102
const { expr } = dataAccessors;
104103

105-
const isRecurrence = !!ExpressionUtils.getField(dataAccessors, 'recurrenceRule', formData);
104+
const isRecurrence = Boolean(dataAccessors.get('recurrenceRule', formData));
106105
const colSpan = isRecurrence ? 1 : 2;
107106

108107
const mainItems = [
@@ -489,12 +488,12 @@ export class AppointmentForm {
489488
const dataAccessors = this.scheduler.getDataAccessors();
490489
const { expr } = dataAccessors;
491490

492-
const rawStartDate = ExpressionUtils.getField(dataAccessors, 'startDate', formData);
493-
const rawEndDate = ExpressionUtils.getField(dataAccessors, 'endDate', formData);
494-
const startDateTimezone = ExpressionUtils.getField(dataAccessors, 'startDateTimeZone', formData) ?? null;
495-
const endDateTimezone = ExpressionUtils.getField(dataAccessors, 'endDateTimeZone', formData) ?? null;
491+
const rawStartDate = dataAccessors.get('startDate', formData);
492+
const rawEndDate = dataAccessors.get('endDate', formData);
493+
const startDateTimezone = dataAccessors.get('startDateTimeZone', formData) ?? null;
494+
const endDateTimezone = dataAccessors.get('endDateTimeZone', formData) ?? null;
496495

497-
const allDay = ExpressionUtils.getField(dataAccessors, 'allDay', formData);
496+
const allDay = dataAccessors.get('allDay', formData);
498497
const startDate = new Date(rawStartDate);
499498
const endDate = new Date(rawEndDate);
500499

packages/devextreme/js/__internal/scheduler/appointment_popup/m_popup.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import $ from '@js/core/renderer';
55
import dateUtils from '@js/core/utils/date';
66
import { Deferred, when } from '@js/core/utils/deferred';
77
import Popup from '@js/ui/popup/ui.popup';
8-
import { ExpressionUtils } from '@ts/scheduler/m_expression_utils';
98
import {
109
getMaxWidth,
1110
getPopupToolbarItems,
@@ -232,7 +231,7 @@ export class AppointmentPopup {
232231
if (this.form.dxForm && this.visible) { // TODO
233232
const { formData } = this.form;
234233
const dataAccessors = this.scheduler.getDataAccessors();
235-
const isRecurrence = ExpressionUtils.getField(dataAccessors, 'recurrenceRule', formData);
234+
const isRecurrence = dataAccessors.get('recurrenceRule', formData);
236235

237236
this.changeSize(isRecurrence);
238237
}
@@ -245,7 +244,7 @@ export class AppointmentPopup {
245244

246245
isShowLoadPanel && this._showLoadPanel();
247246

248-
when(validation && validation.complete || validation).done((validation) => {
247+
when(validation?.complete || validation).done((validation) => {
249248
if (validation && !validation.isValid) {
250249
hideLoading();
251250
deferred.resolve(false);

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 { AppointmentDataAccessor } from '@ts/scheduler/utils';
34

45
import { AppointmentDataSource } from './m_appointment_data_source';
56
import { AppointmentFilterBaseStrategy, AppointmentFilterVirtualStrategy } from './m_appointment_filter';
@@ -14,7 +15,7 @@ export class AppointmentDataProvider {
1415

1516
dataSource: any;
1617

17-
dataAccessors: any;
18+
dataAccessors: AppointmentDataAccessor;
1819

1920
timeZoneCalculator: any;
2021

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
getAppointmentTakesAllDay, getDatesWithoutTime, hasResourceValue, isDateAndTimeView,
1010
isTimelineView,
1111
} from '@ts/scheduler/r1/utils/index';
12+
import type { AppointmentDataAccessor } from '@ts/scheduler/utils';
1213

1314
import { createAppointmentAdapter } from '../../m_appointment_adapter';
1415
import { getRecurrenceProcessor } from '../../m_recurrence';
@@ -35,7 +36,7 @@ const FilterStrategies = {
3536
export class AppointmentFilterBaseStrategy {
3637
options: any;
3738

38-
dataAccessors: any;
39+
dataAccessors: AppointmentDataAccessor;
3940

4041
constructor(options) {
4142
this.options = options;
@@ -160,7 +161,7 @@ export class AppointmentFilterBaseStrategy {
160161
} = filterOptions;
161162

162163
const [trimMin, trimMax] = getDatesWithoutTime(min, max);
163-
const useRecurrence = isDefined(this.dataAccessors.getter.recurrenceRule);
164+
const useRecurrence = this.dataAccessors.has('recurrenceRule');
164165

165166
return [[(appointment) => {
166167
const appointmentVisible = appointment.visible ?? true;
@@ -458,7 +459,6 @@ export class AppointmentFilterVirtualStrategy extends AppointmentFilterBaseStrat
458459
.toArray();
459460
}
460461

461-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
462462
hasAllDayAppointments(filteredItems, preparedItems) {
463463
return this.filterAllDayAppointments(preparedItems).length > 0;
464464
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { describe, expect, it } from '@jest/globals';
2+
import { mockAppointmentDataAccessor } from '@ts/scheduler/__mock__/appointment_data_accessor.mock';
3+
4+
import { replaceWrongEndDate } from './m_utils';
5+
6+
describe('replaceWrongEndDate', () => {
7+
it('should process endDate correctly', () => {
8+
[
9+
{
10+
data: {
11+
startDate: new Date(2019, 4, 3, 12),
12+
allDay: false,
13+
},
14+
expectedEndDate: new Date(2019, 4, 3, 12, 30),
15+
},
16+
{
17+
data: {
18+
startDate: new Date(2019, 4, 3, 12),
19+
allDay: false,
20+
endDate: new Date('string'),
21+
},
22+
expectedEndDate: new Date(2019, 4, 3, 12, 30),
23+
},
24+
{
25+
data: {
26+
startDate: new Date(2019, 4, 3, 12),
27+
allDay: true,
28+
},
29+
expectedEndDate: new Date(2019, 4, 3, 23, 59),
30+
},
31+
].forEach((item) => {
32+
replaceWrongEndDate(
33+
item.data,
34+
new Date(2019, 4, 3, 12),
35+
item.data.endDate,
36+
30,
37+
mockAppointmentDataAccessor,
38+
);
39+
40+
expect((item.data.endDate as Date).getHours()).toBe(item.expectedEndDate.getHours());
41+
expect((item.data.endDate as Date).getMinutes()).toBe(item.expectedEndDate.getMinutes());
42+
});
43+
});
44+
});

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

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import dateUtils from '@js/core/utils/date';
22
import dateSerialization from '@js/core/utils/date_serialization';
3+
import type { AppointmentDataAccessor } from '@ts/scheduler/utils';
34

4-
import { ExpressionUtils } from '../../m_expression_utils';
55
import timeZoneUtils from '../../m_utils_time_zone';
66

77
const toMs = dateUtils.dateToMilliseconds;
@@ -124,7 +124,13 @@ export const _convertRecurrenceException = (exceptionString, startDate, timeZone
124124
return exceptionString;
125125
};
126126

127-
export const replaceWrongEndDate = (rawAppointment, startDate, endDate, appointmentDuration, dataAccessors) => {
127+
export const replaceWrongEndDate = (
128+
rawAppointment,
129+
startDate,
130+
endDate,
131+
appointmentDuration,
132+
dataAccessors: AppointmentDataAccessor,
133+
) => {
128134
const calculateAppointmentEndDate = (isAllDay, startDate) => {
129135
if (isAllDay) {
130136
return dateUtils.setToDayEnd(new Date(startDate));
@@ -134,17 +140,20 @@ export const replaceWrongEndDate = (rawAppointment, startDate, endDate, appointm
134140
};
135141

136142
if (_isEndDateWrong(startDate, endDate)) {
137-
const isAllDay = ExpressionUtils.getField(dataAccessors, 'allDay', rawAppointment);
143+
const isAllDay = Boolean(dataAccessors.get('allDay', rawAppointment));
138144

139145
const calculatedEndDate = calculateAppointmentEndDate(isAllDay, startDate);
140-
dataAccessors.setter.endDate(rawAppointment, calculatedEndDate);
146+
dataAccessors.set('endDate', rawAppointment, calculatedEndDate);
141147
}
142148
};
143149

144-
export const sortAppointmentsByStartDate = (appointments, dataAccessors) => {
150+
export const sortAppointmentsByStartDate = (
151+
appointments,
152+
dataAccessors: AppointmentDataAccessor,
153+
) => {
145154
appointments.sort((a, b) => {
146-
const firstDate = new Date(ExpressionUtils.getField(dataAccessors, 'startDate', a.settings || a));
147-
const secondDate = new Date(ExpressionUtils.getField(dataAccessors, 'startDate', b.settings || b));
155+
const firstDate = new Date(dataAccessors.get('startDate', a.settings || a));
156+
const secondDate = new Date(dataAccessors.get('startDate', b.settings || b));
148157

149158
return Math.sign(firstDate.getTime() - secondDate.getTime());
150159
});

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

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ import {
2828
REDUCED_APPOINTMENT_ICON,
2929
REDUCED_APPOINTMENT_PARTS_CLASSES,
3030
} from '../m_classes';
31-
import { ExpressionUtils } from '../m_expression_utils';
3231
import { getRecurrenceProcessor } from '../m_recurrence';
32+
import type { AppointmentDataAccessor } from '../utils';
3333

3434
const DEFAULT_HORIZONTAL_HANDLES = 'left right';
3535
const DEFAULT_VERTICAL_HANDLES = 'top bottom';
@@ -42,10 +42,14 @@ export class Appointment extends DOMComponent {
4242
return this.$element();
4343
}
4444

45-
get rawAppointment() {
45+
get rawAppointment(): any {
4646
return this.option('data');
4747
}
4848

49+
get dataAccessors(): AppointmentDataAccessor {
50+
return this.option('dataAccessors') as AppointmentDataAccessor;
51+
}
52+
4953
_getDefaultOptions() {
5054
// @ts-expect-error
5155
return extend(super._getDefaultOptions(), {
@@ -282,7 +286,8 @@ export class Appointment extends DOMComponent {
282286
}
283287

284288
_getDate(propName: 'endDate' | 'startDate') {
285-
const result = ExpressionUtils.getField(this.option('dataAccessors'), propName, this.rawAppointment);
289+
const result = this.dataAccessors.get(propName, this.rawAppointment);
290+
286291
if (!result) {
287292
return result;
288293
}
@@ -313,7 +318,7 @@ export class Appointment extends DOMComponent {
313318
}
314319

315320
_renderRecurrenceClass() {
316-
const rule = ExpressionUtils.getField(this.option('dataAccessors'), 'recurrenceRule', this.rawAppointment);
321+
const rule = this.dataAccessors.get('recurrenceRule', this.rawAppointment);
317322

318323
if (getRecurrenceProcessor().isValidRecurrenceRule(rule)) {
319324
(this.$element() as any).addClass(RECURRENCE_APPOINTMENT_CLASS);

0 commit comments

Comments
 (0)