Skip to content
Merged
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
134 changes: 134 additions & 0 deletions packages/devextreme/eslint-scheduler-allowlist.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
const schedulerDOMComponentOverrides = [
'_createActionByOption',
'_defaultOptionsRules',
'_dimensionChanged',
'_dispose',
'_disposed',
'_getDefaultOptions',
'_init',
'_initTemplates',
'_optionChanged',
'_setOptionsByReference',
'_useTemplates',
'_visibilityChanged',
];

const schedulerWidgetOverrides = [
'_activeStateUnit',
'_clean',
'_cleanFocusState',
'_eventBindingTarget',
'_fireContentReadyAction',
'_focusInHandler',
'_focusOutHandler',
'_focusTarget',
'_initMarkup',
'_keyboardHandler',
'_render',
'_renderContent',
'_renderFocusState',
'_renderFocusTarget',
'_supportedKeys',
'_toggleVisibility',
'_createAction',
'_createEventArgs',
'_dataSource',
'_dataSourceChangedHandler',
'_dataSourceOptions',
'_options',
];

const schedulerCollectionWidgetOverrides = [
'_cleanItemContainer',
'_clearDropDownItemsElements',
'_createItemByTemplate',
'_executeItemRenderAction',
'_filteredItems',
'_findItemElementByItem',
'_focusedItemIndexBeforeRender',
'_getItemContent',
'_itemClass',
'_itemClickHandler',
'_itemContainer',
'_moveFocus',
'_postprocessRenderItem',
'_processItemClick',
'_refreshActiveDescendant',
'_renderDirection',
'_renderItem',
'_sortedItems',
];

const schedulerR1Overrides = [
'_propsInfo',
'_value',
'_viewComponent',
];

const schedulerLegacyMembers = [
// workspaces/m_work_space.ts
'_$allDayPanel',
'_$dateTable',
'_$dateTableScrollableContent',
'_$flexContainer',
'_$groupTable',
'_$headerPanel',
'_$headerPanelContainer',
'_$thead',
'_dateTableScrollable',
'_getCellCount',
'_getGroupCount',
'_groupedStrategy',
'_isHorizontalGroupedWorkSpace',
'_shader',
'_sidebarScrollable',

// m_scheduler.ts
'_appointments',
'_compactAppointmentsHelper',
'_dataAccessors',
'_getDragBehavior',
'_isAppointmentBeingUpdated',
'_layoutManager',
'_workSpace',

// appointments/m_appointment_collection.ts
'_renderAppointmentTemplate',

// workspaces/view_model/m_view_data_generator.ts
'_getIntervalDuration',

// workspaces/m_virtual_scrolling.ts
'_renderGrid',

// appointment_popup/m_popup.ts
'_popup',

// appointment_popup/m_legacy_popup.ts
'_ignorePreventScrollEventsDeprecation',

// header/m_header.ts
'_useShortDateFormat',

// header/m_view_switcher.ts
'_wrapperClassExternal',

// utils/options/constants.ts, utils/options/types.ts
'_appointmentTooltipOffset',
'_draggingMode',

// 25_2 only: object literal properties
'_loopFocus',
'_swipeEnabled',
];

const schedulerMemberAllowlist = [
...schedulerDOMComponentOverrides,
...schedulerWidgetOverrides,
...schedulerCollectionWidgetOverrides,
...schedulerR1Overrides,
...schedulerLegacyMembers,
];

export const schedulerMemberAllowlistRegex =
`^(_|__esModule|${schedulerMemberAllowlist.map(s => s.replace(/\$/g, '\\$')).join('|')})$`;
31 changes: 29 additions & 2 deletions packages/devextreme/eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import simpleImportSort from 'eslint-plugin-simple-import-sort';
import { changeRulesToStylistic } from 'eslint-migration-utils';
import unicorn from 'eslint-plugin-unicorn';
import customRules from './eslint_plugins/index.js';
import { schedulerMemberAllowlistRegex } from './eslint-scheduler-allowlist.mjs';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
Expand Down Expand Up @@ -569,7 +570,6 @@ export default [
selector: ['variable', 'function', 'parameter'],
format: null,
leadingUnderscore: 'forbid',
// allow only a single underscore identifier `_` to bypass this rule
filter: {
regex: '^_$',
match: false,
Expand All @@ -578,13 +578,40 @@ export default [
{
selector: 'memberLike',
format: null,
leadingUnderscore: 'allow',
leadingUnderscore: 'forbid',
filter: {
regex: schedulerMemberAllowlistRegex,
match: false,
},
},
],
'devextreme-custom/no-deferred': 'error',
'devextreme-custom/prefer-switch-true': ['error', { minBranches: 3 }],
},
},
// Temporarily allow underscore members in appointments/ (pending refactoring)
{
files: ['js/__internal/scheduler/appointments/**/*.ts?(x)'],
rules: {
'@typescript-eslint/naming-convention': [
'error',
{
selector: ['variable', 'function', 'parameter'],
format: null,
leadingUnderscore: 'forbid',
filter: {
regex: '^_$',
match: false,
},
},
{
selector: 'memberLike',
format: null,
leadingUnderscore: 'allow',
},
],
},
},
// Allow Deferred in m_* scheduler files only
{
files: ['js/__internal/scheduler/**/m_*.ts?(x)'],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,18 +144,18 @@ export class AppointmentForm {

private readonly resourceManager!: ResourceManager;

private _dxForm?: dxForm;
private dxFormInstance?: dxForm;

private _recurrenceForm!: RecurrenceForm;
private recurrenceForm!: RecurrenceForm;

private _popup!: any;

private _$mainGroup?: dxElementWrapper;
private $mainGroup?: dxElementWrapper;

private _$recurrenceGroup?: dxElementWrapper;
private $recurrenceGroup?: dxElementWrapper;

get dxForm(): dxForm {
return this._dxForm as dxForm;
return this.dxFormInstance as dxForm;
}

private get dxPopup(): Popup {
Expand All @@ -168,7 +168,7 @@ export class AppointmentForm {

set readOnly(value: boolean) {
this.dxForm.option('readOnly', value);
this._recurrenceForm.setReadOnly(value);
this.recurrenceForm.setReadOnly(value);
}

get formData(): Record<string, any> {
Expand Down Expand Up @@ -210,10 +210,10 @@ export class AppointmentForm {
}

dispose(): void {
this._dxForm?.dispose();
this._dxForm = undefined;
if (this._recurrenceForm) {
this._recurrenceForm.dxForm = undefined;
this.dxFormInstance?.dispose();
this.dxFormInstance = undefined;
if (this.recurrenceForm) {
this.recurrenceForm.dxForm = undefined;
}
}

Expand All @@ -222,8 +222,8 @@ export class AppointmentForm {

const mainGroup = this.createMainFormGroup();

this._recurrenceForm = new RecurrenceForm(this.scheduler);
const recurrenceGroup = this._recurrenceForm.createRecurrenceFormGroup();
this.recurrenceForm = new RecurrenceForm(this.scheduler);
const recurrenceGroup = this.recurrenceForm.createRecurrenceFormGroup();

const items = [mainGroup, recurrenceGroup];

Expand Down Expand Up @@ -290,7 +290,7 @@ export class AppointmentForm {
}

if (isRecurrenceRuleChanged || startDateExpr === dataField) {
this._recurrenceForm.updateRecurrenceFormValues(
this.recurrenceForm.updateRecurrenceFormValues(
this.recurrenceRuleRaw,
this.startDate,
);
Expand All @@ -305,15 +305,15 @@ export class AppointmentForm {
}
},
onInitialized: (e): void => {
this._dxForm = e.component;
this._recurrenceForm.dxForm = this.dxForm;
this.dxFormInstance = e.component;
this.recurrenceForm.dxForm = this.dxForm;

onInitialized?.call(this, e);
},
onContentReady: (e): void => {
const $formElement = e.component.$element();
this._$mainGroup = $formElement.find(`.${CLASSES.mainGroup}`);
this._$recurrenceGroup = $formElement.find(`.${CLASSES.recurrenceGroup}`);
this.$mainGroup = $formElement.find(`.${CLASSES.mainGroup}`);
this.$recurrenceGroup = $formElement.find(`.${CLASSES.recurrenceGroup}`);

this.alignIconsWithEditors();

Expand Down Expand Up @@ -680,7 +680,7 @@ export class AppointmentForm {
if (e.value === repeatNeverValue) {
this.dxForm.updateData(recurrenceRuleExpr, '');
} else {
const currentRecurrenceRule = this._recurrenceForm.recurrenceRule.toString() ?? '';
const currentRecurrenceRule = this.recurrenceForm.recurrenceRule.toString() ?? '';
const recurrenceRule = new RecurrenceRule(currentRecurrenceRule, this.startDate);
recurrenceRule.frequency = e.value;
this.dxForm.updateData(recurrenceRuleExpr, recurrenceRule.toString());
Expand Down Expand Up @@ -883,16 +883,16 @@ export class AppointmentForm {
this.dxPopup.option('height', configuredHeight);
}

if (this._$mainGroup) {
this._$mainGroup.removeClass(CLASSES.mainHidden);
this._$mainGroup.removeAttr('inert');
if (this.$mainGroup) {
this.$mainGroup.removeClass(CLASSES.mainHidden);
this.$mainGroup.removeAttr('inert');

this.focusFirstFocusableInGroup(this._$mainGroup);
this.focusFirstFocusableInGroup(this.$mainGroup);
}

if (this._$recurrenceGroup) {
this._$recurrenceGroup.addClass(CLASSES.recurrenceHidden);
this._$recurrenceGroup.attr('inert', true);
if (this.$recurrenceGroup) {
this.$recurrenceGroup.addClass(CLASSES.recurrenceHidden);
this.$recurrenceGroup.attr('inert', true);
}

this._popup.updateToolbarForMainGroup();
Expand All @@ -913,23 +913,23 @@ export class AppointmentForm {
this.dxPopup.option('height', overlayHeight);
}

if (this._$mainGroup) {
this._$mainGroup.addClass(CLASSES.mainHidden);
this._$mainGroup.attr('inert', true);
if (this.$mainGroup) {
this.$mainGroup.addClass(CLASSES.mainHidden);
this.$mainGroup.attr('inert', true);
}

if (this._$recurrenceGroup) {
this._$recurrenceGroup.removeClass(CLASSES.recurrenceHidden);
this._$recurrenceGroup.removeAttr('inert');
if (this.$recurrenceGroup) {
this.$recurrenceGroup.removeClass(CLASSES.recurrenceHidden);
this.$recurrenceGroup.removeAttr('inert');

this.focusFirstFocusableInGroup(this._$recurrenceGroup);
this.focusFirstFocusableInGroup(this.$recurrenceGroup);
}

this._popup.updateToolbarForRecurrenceGroup();
}

saveRecurrenceValue(): void {
const { recurrenceRule } = this._recurrenceForm;
const { recurrenceRule } = this.recurrenceForm;
const { recurrenceRuleExpr } = this.scheduler.getDataAccessors().expr;

const recurrenceRuleSerialized = recurrenceRule.toString() ?? '';
Expand Down Expand Up @@ -1046,12 +1046,12 @@ export class AppointmentForm {
}

private updateAnimationOffset(): void {
if (!this._$mainGroup) {
if (!this.$mainGroup) {
return;
}

const formElement = this.dxForm.$element()[0];
const mainGroupElement = this._$mainGroup[0];
const mainGroupElement = this.$mainGroup[0];
const formRect = formElement.getBoundingClientRect();
const groupRect = mainGroupElement.getBoundingClientRect();
const topOffset = groupRect.top - formRect.top;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const POPUP_CONFIG = {
},
},
],
// TODO: legacy property
_ignorePreventScrollEventsDeprecation: true,
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export class AppointmentPopup {

form: AppointmentForm;

// TODO: backing field for popup getter, cannot rename due to name conflict
private _popup?: dxPopup;

private customPopupOptions?: PopupProperties;
Expand Down
Loading
Loading