UNPKG

@devexpress/dx-react-scheduler

Version:

Composable plugin-based scheduler component for React

1 lines 217 kB
{"version":3,"file":"dx-react-scheduler.umd.cjs","sources":["../src/plugins/scheduler-core.tsx","../src/scheduler.tsx","../src/plugins/basic-view.tsx","../src/plugins/vertical-view.tsx","../src/plugins/day-view.tsx","../src/plugins/week-view.tsx","../src/plugins/month-view.tsx","../src/plugins/toolbar.tsx","../src/plugins/date-navigator.tsx","../src/plugins/view-switcher.tsx","../src/plugins/appointments.tsx","../src/plugins/all-day-panel.tsx","../src/plugins/view-state.tsx","../src/plugins/editing-state.tsx","../src/plugins/appointment-tooltip.tsx","../src/plugins/appointment-form.tsx","../src/plugins/drag-drop-provider.tsx","../src/plugins/today-button.tsx","../src/plugins/edit-recurrence-menu.tsx","../src/plugins/integrated-editing.tsx","../src/plugins/resources.tsx","../src/plugins/confirmation-dialog.tsx","../src/plugins/grouping-state.tsx","../src/plugins/grouping-panel.tsx","../src/plugins/current-time-indicator.tsx","../src/plugins/integrated-grouping.tsx"],"sourcesContent":["import * as React from 'react';\nimport {\n Plugin, Getter, Template, TemplatePlaceholder,\n} from '@devexpress/dx-react-core';\nimport { appointments, formatDateTimeGetter } from '@devexpress/dx-scheduler-core';\nimport { SchedulerProps } from '../types';\nimport { memoize } from '@devexpress/dx-core';\n\nclass SchedulerCoreBase extends React.PureComponent<SchedulerProps> {\n formatDateTimeGetter = memoize(locale => formatDateTimeGetter(locale));\n\n render() {\n const {\n data,\n rootComponent: Root,\n locale,\n height,\n firstDayOfWeek,\n } = this.props;\n\n return (\n <Plugin\n name=\"SchedulerCore\"\n >\n <Getter name=\"appointments\" value={appointments(data)} />\n <Getter name=\"formatDate\" value={this.formatDateTimeGetter(locale)} />\n <Getter name=\"firstDayOfWeek\" value={firstDayOfWeek} />\n <Getter name=\"locale\" value={locale} />\n <Template name=\"root\">\n <Root height={height}>\n <TemplatePlaceholder name=\"schedulerRoot\" />\n <TemplatePlaceholder name=\"header\" />\n <TemplatePlaceholder name=\"body\" />\n <TemplatePlaceholder name=\"footer\" />\n </Root>\n </Template>\n </Plugin>\n );\n }\n}\n\n/***\n * The Scheduler is a root container component designed to process\n * and display the specified data. The Scheduler's functionality\n * (data visualization and processing) is implemented in several plugins\n * specified as child components.\n * */\nexport const SchedulerCore: React.ComponentType<SchedulerProps> = SchedulerCoreBase;\n","import * as React from 'react';\nimport { PluginHost } from '@devexpress/dx-react-core';\nimport { SchedulerCore } from './plugins/scheduler-core';\nimport { SchedulerProps } from './types';\n\nconst SchedulerBase: React.FunctionComponent<SchedulerProps> = ({\n data,\n rootComponent,\n children,\n locale,\n height,\n firstDayOfWeek,\n}) => (\n <PluginHost>\n <SchedulerCore\n data={data}\n rootComponent={rootComponent}\n locale={locale}\n height={height}\n firstDayOfWeek={firstDayOfWeek}\n />\n {children}\n </PluginHost>\n);\n\nSchedulerBase.defaultProps = {\n data: [],\n locale: 'en-US',\n height: 'auto',\n firstDayOfWeek: 0,\n};\n\n// tslint:disable: max-line-length\n/***\n * The Scheduler is a root container component designed to process\n * and display the specified data. The Scheduler’s functionality\n * (data visualization and processing) is implemented in several plugins specified as child components.\n * */\nexport const Scheduler: React.ComponentType<SchedulerProps> = SchedulerBase;\n","import * as React from 'react';\nimport {\n Template,\n Plugin,\n Getter,\n TemplateConnector,\n TemplatePlaceholder,\n ComputedFn,\n} from '@devexpress/dx-react-core';\nimport {\n computed,\n startViewDate as startViewDateCore,\n endViewDate as endViewDateCore,\n availableViews as availableViewsCore,\n HORIZONTAL_GROUP_ORIENTATION,\n VERTICAL_GROUP_ORIENTATION,\n} from '@devexpress/dx-scheduler-core';\nimport { memoize } from '@devexpress/dx-core';\nimport { BasicViewProps, BasicViewState, ScrollingStrategy } from '../types';\n\nconst CellPlaceholder = params => <TemplatePlaceholder name=\"cell\" params={params} />;\nconst TimeTableAppointmentLayer = () => <TemplatePlaceholder name=\"timeTableAppointmentLayer\" />;\n\nconst startViewDateBaseComputed = ({ viewCellsData }) => startViewDateCore(viewCellsData);\nconst endViewDateBaseComputed = ({ viewCellsData }) => endViewDateCore(viewCellsData);\n\nconst TimeTablePlaceholder = () => <TemplatePlaceholder name=\"timeTable\" />;\nconst DayScalePlaceholder = () => <TemplatePlaceholder name=\"dayScale\" />;\nconst DayScaleEmptyCellPlaceholder = () => <TemplatePlaceholder name=\"dayScaleEmptyCell\" />;\n\nconst GroupingPanelPlaceholder = () => <TemplatePlaceholder name=\"groupingPanel\" />;\n\nclass BasicViewBase extends React.PureComponent<BasicViewProps, BasicViewState> {\n state = {\n timeTableElementsMeta: {},\n scrollingStrategy: {\n topBoundary: 0,\n bottomBoundary: 0,\n leftBoundary: 0,\n rightBoundary: 0,\n changeVerticalScroll: () => undefined,\n changeHorizontalScroll: () => undefined,\n },\n previousTimeTableCell: null,\n // The key has to be generated every time the TimeTableCell is updated to rerender TimeTable\n // and, consequently, update timeTableElementsMeta\n timeTableLayoutKey: 0,\n };\n\n static getDerivedStateFromProps(\n props: BasicViewProps, state: BasicViewState,\n ): BasicViewState | null {\n\n if (props.timeTableCellComponent !== state.previousTimeTableCell) {\n return {\n ...state,\n previousTimeTableCell: props.timeTableCellComponent,\n timeTableLayoutKey: Math.random(),\n };\n }\n return null;\n }\n\n scrollingStrategyComputed = memoize((viewName, scrollingStrategy) => getters =>\n computed(getters, viewName!, () => scrollingStrategy, getters.scrollingStrategy));\n\n timeTableElementsMetaComputed = memoize((viewName, timeTableElementsMeta) => getters =>\n computed(getters, viewName!, () => timeTableElementsMeta, getters.timeTableElementsMeta));\n\n intervalCountComputed = memoize((viewName, intervalCount) => getters =>\n computed(getters, viewName!, () => intervalCount, getters.intervalCount));\n\n cellDurationComputed = memoize((viewName, cellDuration) => getters =>\n computed(getters, viewName, () => cellDuration, getters.cellDuration));\n\n excludedDaysComputed = memoize((viewName, excludedDays) => getters => computed(\n getters, viewName!, () => excludedDays, getters.excludedDays,\n ));\n\n availableViewsComputed = memoize((viewName, viewDisplayName) => ({ availableViews }) =>\n availableViewsCore(availableViews, viewName!, viewDisplayName));\n\n currentViewComputed = memoize((viewName, viewDisplayName, type) => ({ currentView }) => (\n currentView && currentView.name !== viewName\n ? currentView\n : { name: viewName, type, displayName: viewDisplayName }\n ));\n\n endViewDateComputed: ComputedFn = (getters) => {\n const { name: viewName } = this.props;\n return computed(\n getters, viewName!, endViewDateBaseComputed, getters.endViewDate,\n );\n }\n\n startViewDateComputed: ComputedFn = (getters) => {\n const { name: viewName } = this.props;\n return computed(\n getters, viewName!, startViewDateBaseComputed, getters.startViewDate,\n );\n }\n\n viewCellsDataComputed = memoize((\n viewName, cellDuration, startDayHour, endDayHour, viewCellsDataBaseComputed,\n ) => getters => computed(\n getters,\n viewName,\n viewCellsDataBaseComputed(cellDuration, startDayHour, endDayHour),\n getters.viewCellsData,\n ));\n\n timeTableAppointmentsComputed = memoize((\n viewName, cellDuration, calculateAppointmentsIntervals,\n ) => getters => computed(\n getters,\n viewName,\n calculateAppointmentsIntervals(cellDuration),\n getters.timeTableAppointments,\n ));\n\n updateCellElementsMeta = memoize((cellElementsMeta) => {\n this.setState({ timeTableElementsMeta: cellElementsMeta });\n });\n\n setScrollingStrategy = (scrollingStrategy: ScrollingStrategy) => {\n this.setState({ scrollingStrategy });\n }\n\n render() {\n const {\n name: viewName,\n intervalCount,\n displayName,\n type,\n excludedDays,\n cellDuration,\n startDayHour,\n endDayHour,\n viewCellsDataComputed,\n calculateAppointmentsIntervals,\n dayScaleCellComponent,\n dayScaleRowComponent,\n dayScaleLayoutComponent: DayScale,\n timeTableCellComponent: TimeTableCell,\n timeTableLayoutComponent: TimeTableLayout,\n timeTableRowComponent,\n appointmentLayerComponent: AppointmentLayer,\n dayScaleEmptyCellComponent: DayScaleEmptyCell,\n layoutProps,\n layoutComponent: Layout,\n } = this.props;\n const { timeTableElementsMeta, scrollingStrategy, timeTableLayoutKey } = this.state;\n const viewDisplayName = displayName || viewName;\n\n return (\n <Plugin name=\"basicView\">\n <Getter\n name=\"availableViews\"\n computed={this.availableViewsComputed(viewName, viewDisplayName)}\n />\n <Getter\n name=\"currentView\"\n computed={this.currentViewComputed(viewName, viewDisplayName, type)}\n />\n <Getter\n name=\"intervalCount\"\n computed={this.intervalCountComputed(viewName, intervalCount)}\n />\n <Getter name=\"excludedDays\" computed={this.excludedDaysComputed(viewName, excludedDays)} />\n <Getter\n name=\"viewCellsData\"\n computed={this.viewCellsDataComputed(\n viewName, cellDuration, startDayHour, endDayHour, viewCellsDataComputed,\n )}\n />\n <Getter name=\"startViewDate\" computed={this.startViewDateComputed} />\n <Getter name=\"endViewDate\" computed={this.endViewDateComputed} />\n <Getter\n name=\"cellDuration\"\n computed={this.cellDurationComputed(viewName, cellDuration)}\n />\n\n <Getter\n name=\"timeTableElementsMeta\"\n computed={this.timeTableElementsMetaComputed(viewName, timeTableElementsMeta)}\n />\n <Getter\n name=\"scrollingStrategy\"\n computed={this.scrollingStrategyComputed(viewName, scrollingStrategy)}\n />\n\n <Getter\n name=\"timeTableAppointments\"\n computed={this.timeTableAppointmentsComputed(\n viewName, cellDuration, calculateAppointmentsIntervals,\n )}\n />\n\n <Template name=\"body\">\n { (params: any) =>\n <TemplateConnector>\n {({ currentView, groupOrientation, groups }) => {\n if (currentView.name !== viewName) return <TemplatePlaceholder />;\n const isVerticalGrouping = groupOrientation?.(viewName)\n === VERTICAL_GROUP_ORIENTATION;\n return (\n <Layout\n forwardedRef={params?.forwardedRef}\n dayScaleComponent={DayScalePlaceholder}\n timeTableComponent={TimeTablePlaceholder}\n setScrollingStrategy={this.setScrollingStrategy}\n groupingPanelComponent={\n isVerticalGrouping ? GroupingPanelPlaceholder : undefined\n }\n groupingPanelSize={isVerticalGrouping ? groups?.length : 0}\n dayScaleEmptyCellComponent={DayScaleEmptyCellPlaceholder}\n {...layoutProps}\n />\n );\n }}\n </TemplateConnector>\n }\n </Template>\n\n <Template name=\"dayScale\">\n <TemplateConnector>\n {({ currentView, viewCellsData, formatDate, groupByDate, groupOrientation }) => {\n if (currentView.name !== viewName) return <TemplatePlaceholder />;\n const groupByDateEnabled = groupByDate?.(viewName);\n const isHorizontalGrouping = groupOrientation?.(viewName)\n === HORIZONTAL_GROUP_ORIENTATION;\n return (\n <DayScale\n cellComponent={dayScaleCellComponent}\n rowComponent={dayScaleRowComponent}\n groupingPanelComponent={\n isHorizontalGrouping ? GroupingPanelPlaceholder : undefined\n }\n cellsData={viewCellsData}\n formatDate={formatDate}\n groupedByDate={groupByDateEnabled}\n />\n );\n }}\n </TemplateConnector>\n </Template>\n\n <Template name=\"cell\">\n {params => (\n <TemplateConnector>\n {({ currentView }) => {\n if (currentView.name !== viewName) return <TemplatePlaceholder params={params} />;\n return (\n <TimeTableCell {...params} />\n );\n }}\n </TemplateConnector>\n )}\n </Template>\n\n <Template name=\"timeTable\">\n {(params: any) => (\n <TemplateConnector>\n {({ formatDate, currentView, viewCellsData }) => {\n if (currentView.name !== viewName) return <TemplatePlaceholder />;\n return (\n <>\n <TimeTableLayout\n cellsData={viewCellsData}\n rowComponent={timeTableRowComponent}\n cellComponent={CellPlaceholder}\n formatDate={formatDate}\n setCellElementsMeta={this.updateCellElementsMeta}\n key={timeTableLayoutKey}\n {...params}\n />\n <AppointmentLayer>\n <TimeTableAppointmentLayer />\n </AppointmentLayer>\n </>\n );\n }}\n </TemplateConnector>\n )}\n </Template>\n\n <Template name=\"dayScaleEmptyCell\">\n <TemplateConnector>\n {({ currentView }) => {\n if (currentView.name !== viewName || !DayScaleEmptyCell) {\n return <TemplatePlaceholder />;\n }\n return (\n <DayScaleEmptyCell />\n );\n }}\n </TemplateConnector>\n </Template>\n </Plugin>\n );\n }\n}\nexport const BasicView: React.ComponentType<BasicViewProps> = BasicViewBase;\n","import * as React from 'react';\nimport {\n Template,\n Plugin,\n TemplateConnector,\n TemplatePlaceholder,\n Getter,\n} from '@devexpress/dx-react-core';\nimport {\n calculateWeekDateIntervals,\n getTimeTableHeight,\n timeCellsData as timeCellsDataCore,\n computed,\n} from '@devexpress/dx-scheduler-core';\nimport { BasicView } from './basic-view';\nimport { CommonVerticalViewProps } from '../types';\nimport { memoize } from '@devexpress/dx-core';\n\nconst calculateAppointmentsIntervalsBaseComputed = cellDuration => ({\n appointments, startViewDate, endViewDate, excludedDays,\n}) => calculateWeekDateIntervals(\n appointments, startViewDate, endViewDate, excludedDays, cellDuration,\n);\nconst timeCellsDataComputed = (startDayHour, endDayHour) => ({\n viewCellsData, cellDuration,\n}) => timeCellsDataCore(viewCellsData, startDayHour, endDayHour, cellDuration, Date.now());\n\nconst TimeScalePlaceholder = () => <TemplatePlaceholder name=\"timeScale\" />;\n\nclass VericalViewBase extends React.PureComponent<CommonVerticalViewProps> {\n timeCellsDataComputed = memoize((viewName, startDayHour, endDayHour) => getters => computed(\n getters,\n viewName,\n timeCellsDataComputed(startDayHour, endDayHour),\n getters.timeCellsData,\n ));\n\n render() {\n const {\n layoutComponent,\n dayScaleEmptyCellComponent,\n timeScaleLayoutComponent: TimeScale,\n timeScaleLabelComponent: TimeScaleLabel,\n timeScaleTickCellComponent,\n timeScaleTicksRowComponent,\n dayScaleLayoutComponent,\n dayScaleCellComponent,\n dayScaleRowComponent,\n timeTableLayoutComponent,\n timeTableRowComponent,\n timeTableCellComponent,\n cellDuration,\n excludedDays,\n name: viewName,\n appointmentLayerComponent,\n intervalCount,\n displayName,\n startDayHour,\n endDayHour,\n viewCellsDataComputed,\n type,\n } = this.props;\n\n return (\n <Plugin\n name=\"WeekView\"\n >\n <BasicView\n viewCellsDataComputed={viewCellsDataComputed}\n type={type}\n cellDuration={cellDuration}\n name={viewName}\n intervalCount={intervalCount}\n displayName={displayName}\n startDayHour={startDayHour}\n endDayHour={endDayHour}\n excludedDays={excludedDays}\n calculateAppointmentsIntervals={calculateAppointmentsIntervalsBaseComputed}\n dayScaleEmptyCellComponent={dayScaleEmptyCellComponent}\n dayScaleLayoutComponent={dayScaleLayoutComponent}\n dayScaleCellComponent={dayScaleCellComponent}\n dayScaleRowComponent={dayScaleRowComponent}\n timeTableCellComponent={timeTableCellComponent}\n timeTableLayoutComponent={timeTableLayoutComponent}\n timeTableRowComponent={timeTableRowComponent}\n appointmentLayerComponent={appointmentLayerComponent}\n layoutComponent={layoutComponent}\n layoutProps={{\n timeScaleComponent: TimeScalePlaceholder,\n }}\n />\n\n <Getter\n name=\"timeCellsData\"\n computed={this.timeCellsDataComputed(viewName, startDayHour, endDayHour)}\n />\n\n <Template name=\"timeScale\">\n {(params: any) => (\n <TemplateConnector>\n {({\n currentView, timeCellsData, groups, formatDate,\n groupOrientation: getGroupOrientation,\n timeTableElementsMeta,\n }) => {\n if (currentView.name !== viewName) return <TemplatePlaceholder />;\n const groupOrientation = getGroupOrientation?.(viewName);\n\n return (\n <TimeScale\n labelComponent={TimeScaleLabel}\n tickCellComponent={timeScaleTickCellComponent}\n rowComponent={timeScaleTicksRowComponent}\n cellsData={timeCellsData}\n formatDate={formatDate}\n groups={groups}\n groupOrientation={groupOrientation}\n height={getTimeTableHeight(timeTableElementsMeta)}\n {...params}\n />\n );\n }}\n </TemplateConnector>\n )}\n </Template>\n </Plugin>\n );\n }\n}\n\nexport const VerticalView: React.ComponentType<CommonVerticalViewProps> = VericalViewBase;\n","import * as React from 'react';\nimport {\n Plugin,\n PluginComponents,\n} from '@devexpress/dx-react-core';\nimport {\n viewCellsData as viewCellsDataCore,\n VIEW_TYPES,\n} from '@devexpress/dx-scheduler-core';\nimport { VerticalViewProps } from '../types';\nimport { VerticalView } from './vertical-view';\n\nconst viewCellsDataBaseComputed = (\n cellDuration, startDayHour, endDayHour,\n) => ({ currentDate, intervalCount }) => {\n return viewCellsDataCore(\n currentDate, undefined,\n intervalCount, [],\n startDayHour!, endDayHour!, cellDuration!,\n Date.now(),\n );\n};\n\nclass DayViewBase extends React.PureComponent<VerticalViewProps> {\n static defaultProps: Partial<VerticalViewProps> = {\n name: 'Day',\n startDayHour: 0,\n endDayHour: 24,\n cellDuration: 30,\n intervalCount: 1,\n };\n\n static components: PluginComponents = {\n layoutComponent: 'Layout',\n layoutContainer: 'LayoutContainer',\n appointmentLayerComponent: 'AppointmentLayer',\n dayScaleEmptyCellComponent: 'DayScaleEmptyCell',\n timeScaleLayoutComponent: 'TimeScaleLayout',\n timeScaleLabelComponent: 'TimeScaleLabel',\n timeScaleTickCellComponent: 'TimeScaleTickCell',\n timeScaleTicksRowComponent: 'TimeScaleTicksRow',\n dayScaleLayoutComponent: 'DayScaleLayout',\n dayScaleCellComponent: 'DayScaleCell',\n dayScaleRowComponent: 'DayScaleRow',\n timeTableContainerComponent: 'TimeTableContainer',\n timeTableLayoutComponent: 'TimeTableLayout',\n timeTableCellComponent: 'TimeTableCell',\n timeTableRowComponent: 'TimeTableRow',\n };\n\n render() {\n const {\n layoutComponent,\n dayScaleEmptyCellComponent: DayScaleEmptyCell,\n timeScaleLayoutComponent,\n timeScaleLabelComponent,\n timeScaleTickCellComponent,\n timeScaleTicksRowComponent,\n dayScaleLayoutComponent,\n dayScaleCellComponent,\n dayScaleRowComponent,\n timeTableLayoutComponent,\n timeTableRowComponent,\n timeTableCellComponent,\n appointmentLayerComponent,\n cellDuration,\n name: viewName,\n intervalCount,\n displayName,\n startDayHour,\n endDayHour,\n } = this.props;\n\n return (\n <Plugin\n name=\"DayView\"\n >\n <VerticalView\n viewCellsDataComputed={viewCellsDataBaseComputed}\n type={VIEW_TYPES.DAY}\n cellDuration={cellDuration}\n name={viewName}\n intervalCount={intervalCount}\n displayName={displayName}\n startDayHour={startDayHour}\n endDayHour={endDayHour}\n dayScaleEmptyCellComponent={DayScaleEmptyCell}\n dayScaleLayoutComponent={dayScaleLayoutComponent}\n dayScaleCellComponent={dayScaleCellComponent}\n dayScaleRowComponent={dayScaleRowComponent}\n timeTableCellComponent={timeTableCellComponent}\n timeTableLayoutComponent={timeTableLayoutComponent}\n timeTableRowComponent={timeTableRowComponent}\n appointmentLayerComponent={appointmentLayerComponent}\n layoutComponent={layoutComponent}\n timeScaleLayoutComponent={timeScaleLayoutComponent}\n timeScaleLabelComponent={timeScaleLabelComponent}\n timeScaleTickCellComponent={timeScaleTickCellComponent}\n timeScaleTicksRowComponent={timeScaleTicksRowComponent}\n />\n </Plugin >\n );\n }\n}\n\n// tslint:disable-next-line: max-line-length\n/*** A plugin that renders Scheduler data for a day. This plugin arranges appointments from top to bottom.\n * If their time intervals overlap, their width is decreased and they are placed next to each other.\n * */\nexport const DayView: React.ComponentType<VerticalViewProps> = DayViewBase;\n","import * as React from 'react';\nimport {\n Plugin,\n PluginComponents,\n} from '@devexpress/dx-react-core';\nimport {\n viewCellsData as viewCellsDataCore,\n VIEW_TYPES,\n} from '@devexpress/dx-scheduler-core';\nimport { WeekViewProps } from '../types';\nimport { VerticalView } from './vertical-view';\n\nconst DAYS_IN_WEEK = 7;\nconst viewCellsDataBaseComputed = (\n cellDuration, startDayHour, endDayHour,\n) => ({ firstDayOfWeek, intervalCount, excludedDays, currentDate }) => {\n return viewCellsDataCore(\n currentDate, firstDayOfWeek,\n intervalCount! * DAYS_IN_WEEK, excludedDays!,\n startDayHour!, endDayHour!, cellDuration!,\n Date.now(),\n );\n};\n\nclass WeekViewBase extends React.PureComponent<WeekViewProps> {\n static defaultProps: Partial<WeekViewProps> = {\n startDayHour: 0,\n endDayHour: 24,\n cellDuration: 30,\n intervalCount: 1,\n excludedDays: [],\n name: 'Week',\n };\n\n static components: PluginComponents = {\n layoutComponent: 'Layout',\n layoutContainerComponent: 'LayoutContainer',\n appointmentLayerComponent: 'AppointmentLayer',\n dayScaleEmptyCellComponent: 'DayScaleEmptyCell',\n timeScaleLayoutComponent: 'TimeScaleLayout',\n timeScaleLabelComponent: 'TimeScaleLabel',\n timeScaleTickCellComponent: 'TimeScaleTickCell',\n timeScaleTicksRowComponent: 'TimeScaleTicksRow',\n dayScaleLayoutComponent: 'DayScaleLayout',\n dayScaleCellComponent: 'DayScaleCell',\n dayScaleRowComponent: 'DayScaleRow',\n timeTableContainerComponent: 'TimeTableContainer',\n timeTableLayoutComponent: 'TimeTableLayout',\n timeTableCellComponent: 'TimeTableCell',\n timeTableRowComponent: 'TimeTableRow',\n };\n\n render() {\n const {\n layoutComponent,\n dayScaleEmptyCellComponent,\n timeScaleLayoutComponent,\n timeScaleLabelComponent,\n timeScaleTickCellComponent,\n timeScaleTicksRowComponent,\n dayScaleLayoutComponent,\n dayScaleCellComponent,\n dayScaleRowComponent,\n timeTableLayoutComponent,\n timeTableRowComponent,\n timeTableCellComponent,\n cellDuration,\n excludedDays,\n name: viewName,\n appointmentLayerComponent,\n intervalCount,\n displayName,\n startDayHour,\n endDayHour,\n } = this.props;\n\n return (\n <Plugin\n name=\"WeekView\"\n >\n <VerticalView\n viewCellsDataComputed={viewCellsDataBaseComputed}\n type={VIEW_TYPES.WEEK}\n cellDuration={cellDuration}\n name={viewName}\n intervalCount={intervalCount}\n displayName={displayName}\n startDayHour={startDayHour}\n endDayHour={endDayHour}\n excludedDays={excludedDays}\n dayScaleEmptyCellComponent={dayScaleEmptyCellComponent}\n dayScaleLayoutComponent={dayScaleLayoutComponent}\n dayScaleCellComponent={dayScaleCellComponent}\n dayScaleRowComponent={dayScaleRowComponent}\n timeTableCellComponent={timeTableCellComponent}\n timeTableLayoutComponent={timeTableLayoutComponent}\n timeTableRowComponent={timeTableRowComponent}\n appointmentLayerComponent={appointmentLayerComponent}\n layoutComponent={layoutComponent}\n timeScaleLayoutComponent={timeScaleLayoutComponent}\n timeScaleLabelComponent={timeScaleLabelComponent}\n timeScaleTickCellComponent={timeScaleTickCellComponent}\n timeScaleTicksRowComponent={timeScaleTicksRowComponent}\n />\n </Plugin>\n );\n }\n}\n\n// tslint:disable: max-line-length\n/***\n * A plugin that renders the Scheduler's week view. This plugin arranges appointments from top to bottom.\n * If their time intervals overlap, their width is decreased and they are placed next to each other.\n * */\nexport const WeekView: React.ComponentType<WeekViewProps> = WeekViewBase;\n","import * as React from 'react';\nimport { Plugin, PluginComponents } from '@devexpress/dx-react-core';\nimport { monthCellsData, calculateMonthDateIntervals, VIEW_TYPES } from '@devexpress/dx-scheduler-core';\nimport { BasicView } from './basic-view';\nimport { MonthViewProps } from '../types';\n\nconst viewCellsDataBaseComputed = (\n cellDuration, startDayHour, endDayHour,\n) => ({ currentDate, firstDayOfWeek, intervalCount }) => monthCellsData(\n currentDate, firstDayOfWeek, intervalCount!, Date.now(),\n);\nconst calculateAppointmentsIntervalsBaseComputed = cellDuration => ({\n appointments, startViewDate, endViewDate, excludedDays,\n}) => calculateMonthDateIntervals(\n appointments, startViewDate, endViewDate,\n);\n\nclass MonthViewBase extends React.PureComponent<MonthViewProps> {\n static defaultProps: Partial<MonthViewProps> = {\n intervalCount: 1,\n name: 'Month',\n };\n\n static components: PluginComponents = {\n layoutComponent: 'Layout',\n appointmentLayerComponent: 'AppointmentLayer',\n dayScaleEmptyCellComponent: 'DayScaleEmptyCell',\n dayScaleLayoutComponent: 'DayScaleLayout',\n dayScaleCellComponent: 'DayScaleCell',\n dayScaleRowComponent: 'DayScaleRow',\n timeTableContainerComponent: 'TimeTableContainer',\n timeTableLayoutComponent: 'TimeTableLayout',\n timeTableCellComponent: 'TimeTableCell',\n timeTableRowComponent: 'TimeTableRow',\n };\n\n render() {\n const {\n layoutComponent,\n dayScaleEmptyCellComponent,\n dayScaleLayoutComponent,\n dayScaleCellComponent,\n dayScaleRowComponent,\n timeTableLayoutComponent,\n timeTableRowComponent,\n timeTableCellComponent,\n appointmentLayerComponent,\n name: viewName,\n intervalCount,\n displayName,\n } = this.props;\n\n return (\n <Plugin\n name=\"MonthView\"\n >\n <BasicView\n viewCellsDataComputed={viewCellsDataBaseComputed}\n type={VIEW_TYPES.MONTH}\n name={viewName}\n intervalCount={intervalCount}\n displayName={displayName}\n calculateAppointmentsIntervals={calculateAppointmentsIntervalsBaseComputed}\n dayScaleEmptyCellComponent={dayScaleEmptyCellComponent}\n dayScaleLayoutComponent={dayScaleLayoutComponent}\n dayScaleCellComponent={dayScaleCellComponent}\n dayScaleRowComponent={dayScaleRowComponent}\n timeTableCellComponent={timeTableCellComponent}\n timeTableLayoutComponent={timeTableLayoutComponent}\n timeTableRowComponent={timeTableRowComponent}\n appointmentLayerComponent={appointmentLayerComponent}\n layoutComponent={layoutComponent}\n />\n </Plugin>\n );\n }\n}\n\n// tslint:disable: max-line-length\n/***\n * A plugin that renders Scheduler data for a month. This plugin arranges appointments from left to right.\n * An appointment's size depends on its duration in days.\n * However, it occupies the entire day cell if an appointment lasts only for several hours or minutes.\n * The time scale and all-day panel are not available in this view.\n * */\nexport const MonthView: React.ComponentType<MonthViewProps> = MonthViewBase;\n","import * as React from 'react';\nimport {\n Template,\n Plugin,\n TemplatePlaceholder,\n PluginComponents,\n} from '@devexpress/dx-react-core';\nimport { ToolbarProps } from '../types';\n\nclass ToolbarBase extends React.PureComponent<ToolbarProps> {\n static components: PluginComponents = {\n rootComponent: 'Root',\n flexibleSpaceComponent: 'FlexibleSpace',\n };\n render() {\n const {\n rootComponent: Root,\n flexibleSpaceComponent: FlexibleSpaceComponent,\n } = this.props;\n return (\n <Plugin\n name=\"Toolbar\"\n >\n <Template name=\"header\">\n <Root>\n <TemplatePlaceholder name=\"toolbarContent\" />\n </Root>\n <TemplatePlaceholder />\n </Template>\n <Template name=\"toolbarContent\">\n <FlexibleSpaceComponent />\n </Template>\n </Plugin>\n );\n }\n}\n\n/** A plugin that renders the Scheduler's toolbar. */\nexport const Toolbar: React.ComponentType<ToolbarProps> = ToolbarBase;\n","import * as React from 'react';\nimport {\n Plugin,\n Template,\n TemplatePlaceholder,\n TemplateConnector,\n PluginComponents,\n} from '@devexpress/dx-react-core';\nimport {\n monthCellsData,\n viewBoundText,\n} from '@devexpress/dx-scheduler-core';\nimport { memoize } from '@devexpress/dx-core';\n\nimport { DateNavigatorProps, DateNavigatorState } from '../types';\n\nconst pluginDependencies = [\n { name: 'Toolbar' },\n { name: 'ViewState' },\n];\n\nconst navigate = (action, currentView, intervalCount) => (direction, nextDate) => action({\n direction,\n nextDate,\n amount: intervalCount,\n step: currentView.type,\n});\n\nclass DateNavigatorBase extends React.PureComponent<DateNavigatorProps, DateNavigatorState> {\n target!: React.ReactInstance;\n\n state = {\n visible: false,\n };\n static components: PluginComponents = {\n rootComponent: 'Root',\n overlayComponent: 'Overlay',\n openButtonComponent: 'OpenButton',\n navigationButtonComponent: 'NavigationButton',\n calendarComponent: 'Calendar',\n calendarRowComponent: 'CalendarRow',\n calendarCellComponent: 'CalendarCell',\n calendarHeaderRowComponent: 'CalendarHeaderRow',\n calendarHeaderCellComponent: 'CalendarHeaderCell',\n calendarTextComponent: 'CalendarText',\n calendarNavigatorComponent: 'CalendarNavigator',\n calendarNavigationButtonComponent: 'CalendarNavigationButton',\n };\n\n setRootRef = (target: React.ReactInstance) => {\n this.target = target;\n }\n\n handleVisibilityToggle = () => {\n this.setState(prevState => ({ visible: !prevState.visible }));\n }\n\n handleHide = () => {\n this.setState({ visible: false });\n }\n\n navigateAction = memoize((changeCurrentDate, currentView, intervalCount, navigateAction) =>\n navigateAction(changeCurrentDate, currentView, intervalCount));\n\n render() {\n const {\n rootComponent: Root,\n overlayComponent: Overlay,\n openButtonComponent: OpenButton,\n navigationButtonComponent: NavigationButton,\n calendarComponent: Calendar,\n calendarRowComponent: CalendarRow,\n calendarCellComponent: CalendarCell,\n calendarHeaderRowComponent: CalendarHeaderRow,\n calendarHeaderCellComponent: CalendarHeaderCell,\n calendarTextComponent: CalendarText,\n calendarNavigationButtonComponent: CalendarNavigationButton,\n calendarNavigatorComponent: CalendarNavigator,\n } = this.props;\n\n const { visible } = this.state;\n return (\n <Plugin\n name=\"DateNavigator\"\n dependencies={pluginDependencies}\n >\n <Template name=\"toolbarContent\">\n <TemplateConnector>\n {({\n currentDate,\n startViewDate,\n endViewDate,\n firstDayOfWeek,\n currentView,\n intervalCount,\n formatDate,\n }, {\n changeCurrentDate,\n }) => {\n const navigateAction = this.navigateAction(\n changeCurrentDate, currentView, intervalCount, navigate,\n );\n const calendarDateChanged = (nextDate) => {\n navigateAction(undefined, nextDate);\n this.handleHide();\n };\n const navigatorText = viewBoundText(\n startViewDate,\n endViewDate,\n currentView.type,\n currentDate,\n intervalCount,\n formatDate,\n );\n return (\n <React.Fragment>\n <Root\n navigationButtonComponent={NavigationButton}\n openButtonComponent={OpenButton}\n navigatorText={navigatorText}\n rootRef={this.setRootRef}\n onVisibilityToggle={this.handleVisibilityToggle}\n onNavigate={navigateAction}\n />\n <Overlay\n visible={visible}\n target={this.target}\n onHide={this.handleHide}\n >\n <Calendar\n selectedDate={currentDate}\n firstDayOfWeek={firstDayOfWeek}\n getCells={monthCellsData}\n textComponent={CalendarText}\n navigationButtonComponent={CalendarNavigationButton}\n rowComponent={CalendarRow}\n cellComponent={CalendarCell}\n headerRowComponent={CalendarHeaderRow}\n headerCellComponent={CalendarHeaderCell}\n navigatorComponent={CalendarNavigator}\n onSelectedDateChange={calendarDateChanged}\n formatDate={formatDate}\n />\n </Overlay>\n </React.Fragment>\n );\n }}\n </TemplateConnector>\n <TemplatePlaceholder />\n </Template>\n </Plugin>\n );\n }\n}\n\n/** A plugin that renders the Scheduler’s date navigator. */\nexport const DateNavigator: React.ComponentType<DateNavigatorProps> = DateNavigatorBase;\n","import * as React from 'react';\nimport {\n Plugin,\n Template,\n TemplatePlaceholder,\n TemplateConnector,\n PluginComponents,\n} from '@devexpress/dx-react-core';\nimport { ViewSwitcherProps } from '../types/view-switcher';\n\nconst pluginDependencies = [\n { name: 'Toolbar' },\n { name: 'ViewState' },\n];\n\nclass ViewSwitcherBase extends React.PureComponent<ViewSwitcherProps> {\n static components: PluginComponents = {\n switcherComponent: 'Switcher',\n };\n\n render() {\n const { switcherComponent: Switcher } = this.props;\n\n return (\n <Plugin\n name=\"ViewSwitcher\"\n dependencies={pluginDependencies}\n >\n <Template name=\"toolbarContent\">\n <TemplatePlaceholder />\n <TemplateConnector>\n {({\n currentView,\n availableViews,\n }, {\n setCurrentViewName,\n }) => (\n <Switcher\n currentView={currentView}\n availableViews={availableViews}\n onChange={setCurrentViewName}\n />\n )}\n </TemplateConnector>\n </Template>\n </Plugin>\n );\n }\n}\n\n/** A plugin that renders the Scheduler's view switcher. */\nexport const ViewSwitcher: React.ComponentType<ViewSwitcherProps> = ViewSwitcherBase;\n","import * as React from 'react';\nimport {\n Plugin, Template, TemplatePlaceholder, TemplateConnector, PluginComponents,\n} from '@devexpress/dx-react-core';\nimport { createClickHandlers, memoize } from '@devexpress/dx-core';\nimport {\n POSITION_START, POSITION_END, VERTICAL_TYPE,\n getVerticalRectByAppointmentData, calculateRectByDateAndGroupIntervals,\n getAppointmentStyle, HORIZONTAL_TYPE, getHorizontalRectByAppointmentData,\n isAllDayElementsMetaActual, isTimeTableElementsMetaActual,\n HORIZONTAL_GROUP_ORIENTATION, VIEW_TYPES, getGroupsLastRow, Rect,\n} from '@devexpress/dx-scheduler-core';\n\nimport { AppointmentsProps } from '../types';\n\nconst AppointmentPlaceholder = params => <TemplatePlaceholder name=\"appointment\" params={params} />;\n\nconst renderAppointments = rects => rects.map(({\n dataItem, type: rectType, fromPrev, toNext,\n durationType, resources, key, ...geometry\n}) => (\n <AppointmentPlaceholder\n key={key}\n type={rectType}\n data={dataItem}\n fromPrev={fromPrev}\n toNext={toNext}\n durationType={durationType}\n resources={resources}\n style={getAppointmentStyle(geometry as Rect)}\n />\n));\n\nconst pluginDependencies = [\n { name: 'DayView', optional: true },\n { name: 'WeekView', optional: true },\n { name: 'MonthView', optional: true },\n];\n\nclass AppointmentsBase extends React.PureComponent<AppointmentsProps> {\n static components: PluginComponents = {\n splitIndicatorComponent: 'SplitIndicator',\n containerComponent: 'Container',\n appointmentComponent: 'Appointment',\n appointmentContentComponent: 'AppointmentContent',\n recurringIconComponent: 'RecurringIcon',\n };\n static defaultProps: Partial<AppointmentsProps> = {\n placeAppointmentsNextToEachOther: false,\n };\n\n updateTimeTableAppointments = memoize((\n timeTableAppointments, viewCellsData, timeTableElementsMeta, currentView,\n startViewDate, endViewDate, cellDuration, groups, getGroupOrientation, groupByDate,\n placeAppointmentsNextToEachOther,\n ) => {\n if (!isTimeTableElementsMetaActual(viewCellsData, timeTableElementsMeta)) return null;\n\n const groupOrientation = getGroupOrientation\n ? getGroupOrientation(currentView?.name)\n : HORIZONTAL_GROUP_ORIENTATION;\n const groupCount = groups ? getGroupsLastRow(groups).length : 1;\n\n let appointmentType = { growDirection: VERTICAL_TYPE, multiline: false };\n let getRects = getVerticalRectByAppointmentData as any;\n if (currentView.type === VIEW_TYPES.MONTH) {\n appointmentType = { growDirection: HORIZONTAL_TYPE, multiline: true };\n getRects = getHorizontalRectByAppointmentData;\n }\n\n return renderAppointments(calculateRectByDateAndGroupIntervals(\n appointmentType, timeTableAppointments, getRects,\n {\n startViewDate, endViewDate, cellDuration,\n viewCellsData, cellElementsMeta: timeTableElementsMeta,\n placeAppointmentsNextToEachOther,\n },\n {\n groupOrientation,\n groupedByDate: groupByDate?.(currentView?.name),\n groupCount,\n },\n ));\n });\n\n updateAllDayAppointments = memoize((\n allDayAppointments, viewCellsData, allDayElementsMeta, currentView,\n startViewDate, endViewDate, groups, getGroupOrientation, groupByDate,\n ) => {\n const groupOrientation = getGroupOrientation\n ? getGroupOrientation(currentView?.name)\n : HORIZONTAL_GROUP_ORIENTATION;\n const groupCount = groups ? getGroupsLastRow(groups).length : 1;\n\n if (!isAllDayElementsMetaActual(\n viewCellsData, allDayElementsMeta, groupOrientation, groupCount,\n )) {\n return null;\n }\n\n return renderAppointments(calculateRectByDateAndGroupIntervals(\n { growDirection: HORIZONTAL_TYPE, multiline: false },\n allDayAppointments,\n getHorizontalRectByAppointmentData,\n {\n startViewDate, endViewDate,\n viewCellsData, cellElementsMeta: allDayElementsMeta,\n },\n {\n groupOrientation,\n groupedByDate: groupByDate?.(currentView?.name),\n groupCount,\n },\n ));\n });\n\n render() {\n const {\n splitIndicatorComponent: SplitIndicator,\n appointmentComponent: Appointment,\n appointmentContentComponent: AppointmentContent,\n containerComponent: Container,\n recurringIconComponent,\n placeAppointmentsNextToEachOther,\n } = this.props;\n\n return (\n <Plugin\n name=\"Appointments\"\n dependencies={pluginDependencies}\n >\n <Template\n name=\"timeTableAppointmentLayer\"\n >\n <TemplateConnector>\n {({\n timeTableAppointments, viewCellsData, timeTableElementsMeta, currentView,\n startViewDate, endViewDate, cellDuration, groupOrientation, groups, groupByDate,\n }) => this.updateTimeTableAppointments(\n timeTableAppointments, viewCellsData, timeTableElementsMeta, currentView,\n startViewDate, endViewDate, cellDuration, groups, groupOrientation, groupByDate,\n placeAppointmentsNextToEachOther,\n )}\n </TemplateConnector>\n </Template>\n <Template\n name=\"allDayAppointmentLayer\"\n >\n <TemplateConnector>\n {({\n allDayAppointments, viewCellsData, allDayElementsMeta,\n startViewDate, endViewDate, groupOrientation, currentView, groups, groupByDate,\n }) => this.updateAllDayAppointments(\n allDayAppointments, viewCellsData, allDayElementsMeta, currentView,\n startViewDate, endViewDate, groups, groupOrientation, groupByDate,\n )}\n </TemplateConnector>\n </Template>\n <Template\n name=\"appointment\"\n >\n {({ style, ...params }: any) => (\n <TemplateConnector>\n {({ formatDate }) => (\n <Container style={style}>\n <TemplatePlaceholder\n name=\"appointmentTop\"\n params={{ data: params.data, type: params.type, slice: params.fromPrev }}\n />\n <TemplatePlaceholder\n name=\"appointmentContent\"\n params={{ ...params, formatDate }}\n />\n <TemplatePlaceholder\n name=\"appointmentBottom\"\n params={{ data: params.data, type: params.type, slice: params.toNext }}\n />\n </Container>\n )}\n </TemplateConnector>\n )}\n </Template>\n\n <Template name=\"appointmentContent\">\n {({\n onClick, onDoubleClick, formatDate,\n data, type, fromPrev, toNext,\n durationType, resources, forwardedRef,\n ...restParams\n }: any) => (\n <Appointment\n forwardedRef={forwardedRef}\n data={data}\n resources={resources}\n {...createClickHandlers(onClick, onDoubleClick)}\n {...restParams}\n >\n {fromPrev && <SplitIndicator position={POSITION_START} appointmentType={type} />}\n <AppointmentContent\n data={data}\n type={type}\n durationType={durationType}\n recurringIconComponent={recurringIconComponent}\n formatDate={formatDate}\n resources={resources}\n />\n {toNext && <SplitIndicator position={POSITION_END} appointmentType={type} />}\n </Appointment>\n )}\n </Template>\n </Plugin>\n );\n }\n}\n\n/** A plugin that renders appointments. */\nexport const Appointments: React.ComponentType<AppointmentsProps> = AppointmentsBase;\n","import * as React from 'react';\nimport { getMessagesFormatter, memoize } from '@devexpress/dx-core';\nimport {\n Getter,\n Plugin,\n Template,\n TemplatePlaceholder,\n TemplateConnector,\n PluginComponents,\n} from '@devexpress/dx-react-core';\nimport {\n allDayCells, calculateAllDayDateIntervals,\n VERTICAL_GROUP_ORIENTATION, VIEW_TYPES,\n} from '@devexpress/dx-scheduler-core';\nimport moment from 'moment';\n\nimport { AllDayPanelProps, AllDayPanelState } from '../types';\n\nconst isMonthView = currentView => currentView.type === VIEW_TYPES.MONTH;\nconst isVerticalGrouping = (\n currentView, groupOrientation,\n) => groupOrientation?.(currentView.name) === VERTICAL_GROUP_ORIENTATION;\n\nconst pluginDependencies = [\n { name: 'DayView', optional: true },\n { name: 'WeekView', optional: true },\n];\nconst defaultMessages = {\n allDay: 'All Day',\n};\nconst AllDayAppointmentLayerPlaceholder = () =>\n <TemplatePlaceholder name=\"allDayAppointmentLayer\" />;\nconst AllDayPanelPlaceholder = params => <TemplatePlaceholder name=\"allDayPanel\" params={params} />;\nconst CellPlaceholder = params => <TemplatePlaceholder name=\"allDayPanelCell\" params={params} />;\nconst AllDayTitlePlaceholder = params => <TemplatePlaceholder name=\"allDayTitle\" params={params} />;\n\nclass AllDayPanelBase extends React.PureComponent<AllDayPanelProps, AllDayPanelState> {\n state: AllDayPanelState = {\n elementsMeta: {},\n previousCell: null,\n // The key has to be generated every time the Cell component is updated to rerender the Layout\n // and, consequently, update allDayElementsMeta\n layoutKey: 0,\n };\n static defaultProps: Partial<AllDayPanelProps> = {\n messages: {},\n };\n static components: PluginComponents = {\n appointmentLayerComponent: 'AppointmentLayer',\n layoutComponent: 'Layout',\n layoutContainerComponent: 'LayoutContainer',\n cellComponent: 'Cell',\n rowComponent: 'Row',\n titleCellComponent: 'TitleCell',\n containerComponent: 'Container',\n };\n\n static getDerivedStateFromProps(\n props: AllDayPanelProps, state: AllDayPanelState,\n ): AllDayPanelState | null {\n if (props.cellComponent !== state.previousCell) {\n return {\n ...state,\n previousCell: props.cellComponent,\n layoutKey: Math.random(),\n };\n }\n return null;\n }\n\n allDayCellsDataComputed = memoize(({ viewCellsData }) => allDayCells(viewCellsData));\n\n updateCellElementsMeta = memoize((cellElementsMeta) => {\n this.setState({ elementsMeta: cellElementsMeta });\n });\n\n allDayAppointmentsComputed = memoize(({\n appointments, startViewDate, endViewDate, excludedDays,\n }) => {\n const allDayLeftBound = moment(startViewDate).hours(0).minutes(0).toDate();\n const allDayRightBound = moment(endViewDate).hours(23).minutes(59).toDate();\n return calculateAllDayDateIntervals(\n appointments, allDayLeftBound, allDayRightBound, excludedDays,\n );\n });\n\n allDayPanelExistsComputed = memoize(({\n currentView,\n }) => !isMonthView(currentView));\n\n getMessageFormatter = memoize((messages, allDayPanelDefaultMessages) =>\n getMessagesFormatter({ ...allDayPanelDefaultMessages, ...messages }));\n\n render() {\n const {\n appointmentLayerComponent: AppointmentLayer,\n layoutComponent: Layout,\n cellComponent: Cell,\n rowComponent,\n titleCellComponent: TitleCell,\n containerComponent: Container,\n messages,\n } = this.props;\n const { elementsMeta, layoutKey } = this.state;\n const getMessage = this.getMessageFormatter(messages, defaultMessages);\n\n return (\n <Plugin\n name=\"AllDayPanel\"\n dependencies={pluginDependencies}\n >\n <Getter name=\"allDayElementsMeta\" value={elementsMeta} />\n <Getter name=\"allDayCellsData\" computed={this.allDayCellsDataComputed} />\n <Getter name=\"allDayPanelExists\" computed={this.allDayPanelExistsComputed} />\n <Getter\n name=\"allDayAppointments\"\n