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
19 changes: 19 additions & 0 deletions packages/devextreme/eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,25 @@ export default [
'devextreme-custom/no-deferred': 'off',
},
},
// Strict TypeScript rules for scheduler/header
{
files: ['js/__internal/scheduler/header/**/*.ts?(x)'],
languageOptions: {
parser: tsParser,
ecmaVersion: 5,
sourceType: 'script',
parserOptions: {
project: './tsconfig.json',
tsconfigRootDir: `${__dirname}/js/__internal`,
},
},
rules: {
'@typescript-eslint/no-explicit-any': 'error',
'@typescript-eslint/explicit-function-return-type': 'error',
'@typescript-eslint/no-unsafe-return': 'error',
'@typescript-eslint/explicit-module-boundary-types': 'error',
},
},
// Rules for grid controls
{
files: [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ToolbarModel } from '@ts/scheduler/__tests__/__mock__/model/toolbar';

import { APPOINTMENT_POPUP_CLASS } from '../../../appointment_popup/m_popup';
import { APPOINTMENT_POPUP_CLASS } from '../../../appointment_popup/components/m_popup';
import { POPUP_DIALOG_CLASS } from '../../../m_scheduler';
import type { AppointmentModel } from './appointment';
import { createAppointmentModel } from './appointment';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,17 @@ import { current, isFluent } from '@js/ui/themes';
import { dateSerialization } from '@ts/core/utils/m_date_serialization';
import type Popup from '@ts/ui/popup/m_popup';

import timeZoneUtils from '../m_utils_time_zone';
import type { SafeAppointment } from '../types';
import type { ResourceLoader } from '../utils/loader/resource_loader';
import { DEFAULT_ICONS_SHOW_MODE } from '../utils/options/constants';
import { getAppointmentGroupIndex, getRawAppointmentGroupValues, getSafeGroupValues } from '../utils/resource_manager/appointment_groups_utils';
import type { ResourceManager } from '../utils/resource_manager/resource_manager';
import { customizeFormItems } from './m_customize_form_items';
import { RecurrenceForm } from './m_recurrence_form';
import { createFormIconTemplate, getStartDateCommonConfig, RecurrenceRule } from './utils';

const CLASSES = {
import timeZoneUtils from '../../../m_utils_time_zone';
import type { SafeAppointment } from '../../../types';
import type { ResourceLoader } from '../../../utils/loader/resource_loader';
import { DEFAULT_ICONS_SHOW_MODE } from '../../../utils/options/constants';
import { getAppointmentGroupIndex, getRawAppointmentGroupValues, getSafeGroupValues } from '../../../utils/resource_manager/appointment_groups_utils';
import type { ResourceManager } from '../../../utils/resource_manager/resource_manager';
import { customizeFormItems } from '../../factories/customize_form_items/m_customize_form_items';
import { createFormIconTemplate, getStartDateCommonConfig, RecurrenceRule } from '../../utils';
import { RecurrenceForm } from '../recurrence_form/m_recurrence_form';

const FORM_CLASSES = {
form: 'dx-scheduler-form',
icon: 'dx-icon',
hidden: 'dx-hidden',
Expand Down Expand Up @@ -260,7 +260,7 @@ export class AppointmentForm {
xs: 1,
},
elementAttr: {
class: CLASSES.form,
class: FORM_CLASSES.form,
},
onFieldDataChanged: (e) => {
const {
Expand Down Expand Up @@ -304,8 +304,8 @@ export class AppointmentForm {
},
onContentReady: (e): void => {
const $formElement = e.component.$element();
this._$mainGroup = $formElement.find(`.${CLASSES.mainGroup}`);
this._$recurrenceGroup = $formElement.find(`.${CLASSES.recurrenceGroup}`);
this._$mainGroup = $formElement.find(`.${FORM_CLASSES.mainGroup}`);
this._$recurrenceGroup = $formElement.find(`.${FORM_CLASSES.recurrenceGroup}`);

onContentReady?.call(this, e);
},
Expand All @@ -320,7 +320,7 @@ export class AppointmentForm {
name: MAIN_GROUP_NAME,
itemType: 'group',
colSpan: 1,
cssClass: CLASSES.mainGroup,
cssClass: FORM_CLASSES.mainGroup,
items: [
this.createSubjectGroup(),
this.createDateRangeGroup(),
Expand All @@ -337,7 +337,7 @@ export class AppointmentForm {
return {
name: SUBJECT_GROUP_NAME,
itemType: 'group',
cssClass: `${CLASSES.subjectGroup} ${CLASSES.groupWithIcon}`,
cssClass: `${FORM_CLASSES.subjectGroup} ${FORM_CLASSES.groupWithIcon}`,
colCount: 2,
colCountByScreen: {
xs: 2,
Expand All @@ -346,14 +346,14 @@ export class AppointmentForm {
{
name: SUBJECT_ICON_NAME,
colSpan: 1,
cssClass: CLASSES.formIcon,
cssClass: FORM_CLASSES.formIcon,
template: createFormIconTemplate('isnotblank'),
},
{
name: SUBJECT_EDITOR_NAME,
colSpan: 1,
itemType: 'simple',
cssClass: CLASSES.textEditor,
cssClass: FORM_CLASSES.textEditor,
dataField: textExpr,
label: {
text: messageLocalization.format('dxScheduler-editorLabelTitle'),
Expand All @@ -368,7 +368,7 @@ export class AppointmentForm {
return {
name: DATE_GROUP_NAME,
itemType: 'group',
cssClass: `${CLASSES.dateRangeGroup} ${CLASSES.groupWithIcon}`,
cssClass: `${FORM_CLASSES.dateRangeGroup} ${FORM_CLASSES.groupWithIcon}`,
colCount: 2,
colCountByScreen: {
xs: 2,
Expand All @@ -377,7 +377,7 @@ export class AppointmentForm {
{
name: DATE_ICON_NAME,
colSpan: 1,
cssClass: CLASSES.formIcon,
cssClass: FORM_CLASSES.formIcon,
template: createFormIconTemplate('clock'),
},
{
Expand All @@ -401,7 +401,7 @@ export class AppointmentForm {
name: ALL_DAY_EDITOR_NAME,
itemType: 'simple',
dataField: allDayExpr,
cssClass: CLASSES.allDaySwitch,
cssClass: FORM_CLASSES.allDaySwitch,
label: {
text: messageLocalization.format('dxScheduler-allDay'),
location: 'left',
Expand Down Expand Up @@ -445,18 +445,18 @@ export class AppointmentForm {
startDateExpr,
{
name: START_DATE_GROUP_NAME,
cssClass: CLASSES.startDateGroup,
cssClass: FORM_CLASSES.startDateGroup,
},
{
name: START_DATE_EDITOR_NAME,
label: {
text: messageLocalization.format('dxScheduler-editorLabelStartDate'),
},
cssClass: CLASSES.startDateEditor,
cssClass: FORM_CLASSES.startDateEditor,
},
{
name: START_TIME_EDITOR_NAME,
cssClass: CLASSES.startTimeEditor,
cssClass: FORM_CLASSES.startTimeEditor,
editorOptions: {
inputAttr: {
'aria-label': messageLocalization.format('dxScheduler-editorAriaLabelStartTime'),
Expand All @@ -466,7 +466,7 @@ export class AppointmentForm {
{
name: START_DATE_TIMEZONE_EDITOR_NAME,
dataField: startDateTimeZoneExpr,
cssClass: CLASSES.startDateTimeZoneEditor,
cssClass: FORM_CLASSES.startDateTimeZoneEditor,
editorOptions: {
onValueChanged: (e) => {
const endDateTimeZoneEditor = this.dxForm.getEditor(endDateTimeZoneExpr);
Expand All @@ -485,18 +485,18 @@ export class AppointmentForm {
endDateExpr,
{
name: END_DATE_GROUP_NAME,
cssClass: CLASSES.endDateGroup,
cssClass: FORM_CLASSES.endDateGroup,
},
{
name: END_DATE_EDITOR_NAME,
label: {
text: messageLocalization.format('dxScheduler-editorLabelEndDate'),
},
cssClass: CLASSES.endDateEditor,
cssClass: FORM_CLASSES.endDateEditor,
},
{
name: END_TIME_EDITOR_NAME,
cssClass: CLASSES.endTimeEditor,
cssClass: FORM_CLASSES.endTimeEditor,
editorOptions: {
inputAttr: {
'aria-label': messageLocalization.format('dxScheduler-editorAriaLabelEndTime'),
Expand All @@ -506,7 +506,7 @@ export class AppointmentForm {
{
name: END_DATE_TIMEZONE_EDITOR_NAME,
dataField: endDateTimeZoneExpr,
cssClass: CLASSES.endDateTimeZoneEditor,
cssClass: FORM_CLASSES.endDateTimeZoneEditor,
},
);
}
Expand Down Expand Up @@ -654,19 +654,19 @@ export class AppointmentForm {
colCountByScreen: {
xs: 2,
},
cssClass: `${CLASSES.repeatGroup} ${CLASSES.groupWithIcon}`,
cssClass: `${FORM_CLASSES.repeatGroup} ${FORM_CLASSES.groupWithIcon}`,
items: [
{
name: REPEAT_ICON_NAME,
colSpan: 1,
cssClass: CLASSES.formIcon,
cssClass: FORM_CLASSES.formIcon,
template: createFormIconTemplate('repeat'),
},
{
name: REPEAT_EDITOR_NAME,
colSpan: 1,
itemType: 'simple',
cssClass: CLASSES.repeatEditor,
cssClass: FORM_CLASSES.repeatEditor,
label: {
text: messageLocalization.format('dxScheduler-editorLabelRecurrence'),
},
Expand Down Expand Up @@ -710,20 +710,20 @@ export class AppointmentForm {
colCountByScreen: {
xs: 2,
},
cssClass: `${CLASSES.descriptionGroup} ${CLASSES.groupWithIcon}`,
cssClass: `${FORM_CLASSES.descriptionGroup} ${FORM_CLASSES.groupWithIcon}`,
items: [
{
name: DESCRIPTION_ICON_NAME,
colSpan: 1,
cssClass: CLASSES.formIcon,
cssClass: FORM_CLASSES.formIcon,
template: createFormIconTemplate('description'),
},
{
name: DESCRIPTION_EDITOR_NAME,
dataField: descriptionExpr,
colSpan: 1,
itemType: 'simple',
cssClass: CLASSES.descriptionEditor,
cssClass: FORM_CLASSES.descriptionEditor,
label: {
text: messageLocalization.format('dxScheduler-editorLabelDescription'),
},
Expand Down Expand Up @@ -771,12 +771,12 @@ export class AppointmentForm {
colCountByScreen: {
xs: 2,
},
cssClass: `${CLASSES.resourcesGroup} ${CLASSES.groupWithIcon}`,
cssClass: `${FORM_CLASSES.resourcesGroup} ${FORM_CLASSES.groupWithIcon}`,
items: [
{
name: `${RESOURCES_GROUP_NAME}Icon`,
colSpan: 1,
cssClass: `${CLASSES.formIcon} ${CLASSES.defaultResourceIcon}`,
cssClass: `${FORM_CLASSES.formIcon} ${FORM_CLASSES.defaultResourceIcon}`,
template: createFormIconTemplate('addcircleoutline'),
},
{
Expand All @@ -800,12 +800,12 @@ export class AppointmentForm {
colCountByScreen: {
xs: 2,
},
cssClass: CLASSES.groupWithIcon,
cssClass: FORM_CLASSES.groupWithIcon,
items: [
{
colSpan: 1,
name: `${dataField}Icon`,
cssClass: CLASSES.formIcon,
cssClass: FORM_CLASSES.formIcon,
template: createFormIconTemplate(icon),
},
item,
Expand All @@ -820,20 +820,20 @@ export class AppointmentForm {
colCountByScreen: {
xs: 1,
},
cssClass: CLASSES.resourcesGroup,
cssClass: FORM_CLASSES.resourcesGroup,
items: resourcesItems,
} as GroupItem;
}

private setStylingModeToEditors(item: FormItem, showIcon: boolean): void {
const itemClasses = (item.cssClass ?? '').split(' ');
const isIconItem = itemClasses.includes(CLASSES.formIcon);
const isIconItem = itemClasses.includes(FORM_CLASSES.formIcon);

if (isIconItem) {
const isHidden = itemClasses.includes(CLASSES.hidden);
const isHidden = itemClasses.includes(FORM_CLASSES.hidden);

if (!showIcon && !isHidden) {
item.cssClass += ` ${CLASSES.hidden}`;
item.cssClass += ` ${FORM_CLASSES.hidden}`;
}

return;
Expand Down Expand Up @@ -870,14 +870,14 @@ export class AppointmentForm {
}

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

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

if (this._$recurrenceGroup) {
this._$recurrenceGroup.addClass(CLASSES.recurrenceHidden);
this._$recurrenceGroup.addClass(FORM_CLASSES.recurrenceHidden);
this._$recurrenceGroup.attr('inert', true);
}
}
Expand All @@ -893,12 +893,12 @@ export class AppointmentForm {
}

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

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

this.focusFirstFocusableInGroup(this._$recurrenceGroup);
Expand Down Expand Up @@ -935,7 +935,7 @@ export class AppointmentForm {
groupIndex,
});

const $icon = this.dxForm.$element().find(`.${CLASSES.subjectGroup} .${CLASSES.formIcon} .${CLASSES.icon}`);
const $icon = this.dxForm.$element().find(`.${FORM_CLASSES.subjectGroup} .${FORM_CLASSES.formIcon} .${FORM_CLASSES.icon}`);

$icon.css('color', color ?? '');
}
Expand Down Expand Up @@ -988,7 +988,7 @@ export class AppointmentForm {
this.showRecurrenceGroup();
},
elementAttr: {
class: `${CLASSES.recurrenceSettingsButton} dx-shape-standard`,
class: `${FORM_CLASSES.recurrenceSettingsButton} dx-shape-standard`,
},
},
});
Expand Down Expand Up @@ -1023,7 +1023,7 @@ export class AppointmentForm {
}

private focusFirstFocusableInGroup($group: dxElementWrapper): void {
const focusTarget = $group.find(`.${CLASSES.fieldItemContent} [tabindex]`).first().get(0) as HTMLElement;
const focusTarget = $group.find(`.${FORM_CLASSES.fieldItemContent} [tabindex]`).first().get(0) as HTMLElement;
focusTarget?.focus({ preventScroll: true });
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import type { GroupItem, Item as FormItem } from '@js/ui/form';
import type { ToolbarItem } from '@js/ui/popup';
import { toMilliseconds } from '@ts/utils/toMilliseconds';

import fx from '../../../common/core/animation/fx';
import { createScheduler } from '../__tests__/__mock__/create_scheduler';
import { setupSchedulerTestEnvironment } from '../__tests__/__mock__/m_mock_scheduler';
import { DEFAULT_SCHEDULER_OPTIONS } from '../utils/options/constants';
import fx from '../../../../common/core/animation/fx';
import { createScheduler } from '../../__tests__/__mock__/create_scheduler';
import { setupSchedulerTestEnvironment } from '../../__tests__/__mock__/m_mock_scheduler';
import { DEFAULT_SCHEDULER_OPTIONS } from '../../utils/options/constants';

const CLASSES = {
icon: 'dx-scheduler-form-icon',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ import type dxPopup from '@js/ui/popup';
import Popup from '@js/ui/popup/ui.popup';
import { current, isFluent } from '@js/ui/themes';

import { hide as hideLoading, show as showLoading } from '../m_loading';
import type { SafeAppointment } from '../types';
import { AppointmentAdapter } from '../utils/appointment_adapter/appointment_adapter';
import { getAppointmentGroupValues, getRawAppointmentGroupValues } from '../utils/resource_manager/appointment_groups_utils';
import type { AppointmentForm } from './m_form';
import { hide as hideLoading, show as showLoading } from '../../m_loading';
import type { SafeAppointment } from '../../types';
import { AppointmentAdapter } from '../../utils/appointment_adapter/appointment_adapter';
import { getAppointmentGroupValues, getRawAppointmentGroupValues } from '../../utils/resource_manager/appointment_groups_utils';
import type { AppointmentForm } from './form/m_form';

export const APPOINTMENT_POPUP_CLASS = 'dx-scheduler-appointment-popup';

Expand Down
Loading