devextreme
Version:
JavaScript/TypeScript Component Suite for Responsive Web Development
1,172 lines • 114 kB
JavaScript
/**
* DevExtreme (esm/__internal/scheduler/workspaces/m_work_space.js)
* Version: 25.2.7
* Build date: Tue May 05 2026
*
* Copyright (c) 2012 - 2026 Developer Express Inc. ALL RIGHTS RESERVED
* Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
*/
import {
locate,
resetPosition
} from "../../../common/core/animation/translator";
import {
name as clickEventName
} from "../../../common/core/events/click";
import {
name as contextMenuEventName
} from "../../../common/core/events/contextmenu";
import eventsEngine from "../../../common/core/events/core/events_engine";
import {
drop as dragEventDrop,
enter as dragEventEnter,
leave as dragEventLeave
} from "../../../common/core/events/drag";
import pointerEvents from "../../../common/core/events/pointer";
import {
addNamespace,
isMouseEvent
} from "../../../common/core/events/utils/index";
import messageLocalization from "../../../common/core/localization/message";
import domAdapter from "../../../core/dom_adapter";
import {
getPublicElement
} from "../../../core/element";
import $ from "../../../core/renderer";
import {
noop
} from "../../../core/utils/common";
import {
compileGetter
} from "../../../core/utils/data";
import dateUtils from "../../../core/utils/date";
import {
extend
} from "../../../core/utils/extend";
import {
getBoundingRect
} from "../../../core/utils/position";
import {
getHeight,
getOuterHeight,
getOuterWidth,
getWidth,
setOuterHeight,
setWidth
} from "../../../core/utils/size";
import {
isDefined
} from "../../../core/utils/type";
import {
getWindow,
hasWindow
} from "../../../core/utils/window";
import errors from "../../../ui/widget/ui.errors";
import Widget from "../../../ui/widget/ui.widget";
import {
getMemoizeScrollTo
} from "../../core/utils/scroll";
import {
AllDayPanelTitleComponent,
AllDayTableComponent,
DateTableComponent,
GroupPanelComponent,
HeaderPanelComponent,
TimePanelComponent
} from "../../scheduler/r1/components/index";
import {
calculateIsGroupedAllDayPanel,
calculateViewStartDate,
getCellDuration,
getStartViewDateTimeOffset,
getViewStartByOptions,
isDateAndTimeView
} from "../../scheduler/r1/utils/index";
import Scrollable from "../../ui/scroll_view/scrollable";
import {
APPOINTMENT_SETTINGS_KEY
} from "../constants";
import {
Cache
} from "../global_cache";
import AppointmentDragBehavior from "../m_appointment_drag_behavior";
import {
APPOINTMENT_DRAG_SOURCE_CLASS,
DATE_TABLE_CLASS,
DATE_TABLE_ROW_CLASS,
FIXED_CONTAINER_CLASS,
GROUP_HEADER_CONTENT_CLASS,
GROUP_ROW_CLASS,
TIME_PANEL_CLASS,
VERTICAL_GROUP_COUNT_CLASSES,
VIRTUAL_CELL_CLASS
} from "../m_classes";
import {
CompactAppointmentsHelper
} from "../m_compact_appointments_helper";
import tableCreatorModule from "../m_table_creator";
import {
utils
} from "../m_utils";
import VerticalShader from "../shaders/current_time_shader_vertical";
import {
getAppointmentGroupIndex,
getSafeGroupValues
} from "../utils/resource_manager/appointment_groups_utils";
import {
getLeafGroupValues
} from "../utils/resource_manager/group_utils";
import {
getAllDayHeight,
getCellHeight,
getCellWidth,
getMaxAllowedPosition,
PositionHelper
} from "./helpers/m_position_helper";
import {
CellsSelectionController
} from "./m_cells_selection_controller";
import CellsSelectionState from "./m_cells_selection_state";
import {
VirtualScrollingDispatcher,
VirtualScrollingRenderer
} from "./m_virtual_scrolling";
import HorizontalGroupedStrategy from "./m_work_space_grouped_strategy_horizontal";
import VerticalGroupedStrategy from "./m_work_space_grouped_strategy_vertical";
import ViewDataProvider from "./view_model/m_view_data_provider";
const {
tableCreator: tableCreator
} = tableCreatorModule;
const DRAGGING_MOUSE_FAULT = 10;
const {
abstract: abstract
} = Widget;
const toMs = dateUtils.dateToMilliseconds;
const COMPONENT_CLASS = "dx-scheduler-work-space";
const GROUPED_WORKSPACE_CLASS = "dx-scheduler-work-space-grouped";
const VERTICAL_GROUPED_WORKSPACE_CLASS = "dx-scheduler-work-space-vertical-grouped";
const WORKSPACE_VERTICAL_GROUP_TABLE_CLASS = "dx-scheduler-work-space-vertical-group-table";
const WORKSPACE_WITH_BOTH_SCROLLS_CLASS = "dx-scheduler-work-space-both-scrollbar";
const WORKSPACE_WITH_COUNT_CLASS = "dx-scheduler-work-space-count";
const WORKSPACE_WITH_GROUP_BY_DATE_CLASS = "dx-scheduler-work-space-group-by-date";
const WORKSPACE_WITH_ODD_CELLS_CLASS = "dx-scheduler-work-space-odd-cells";
const TIME_PANEL_CELL_CLASS = "dx-scheduler-time-panel-cell";
const TIME_PANEL_ROW_CLASS = "dx-scheduler-time-panel-row";
const ALL_DAY_PANEL_CLASS = "dx-scheduler-all-day-panel";
const ALL_DAY_TABLE_CLASS = "dx-scheduler-all-day-table";
const ALL_DAY_CONTAINER_CLASS = "dx-scheduler-all-day-appointments";
const ALL_DAY_TITLE_CLASS = "dx-scheduler-all-day-title";
const ALL_DAY_TABLE_CELL_CLASS = "dx-scheduler-all-day-table-cell";
const ALL_DAY_TABLE_ROW_CLASS = "dx-scheduler-all-day-table-row";
const WORKSPACE_WITH_ALL_DAY_CLASS = "dx-scheduler-work-space-all-day";
const WORKSPACE_WITH_COLLAPSED_ALL_DAY_CLASS = "dx-scheduler-work-space-all-day-collapsed";
const WORKSPACE_WITH_MOUSE_SELECTION_CLASS = "dx-scheduler-work-space-mouse-selection";
const HORIZONTAL_SIZES_CLASS = "dx-scheduler-cell-sizes-horizontal";
const VERTICAL_SIZES_CLASS = "dx-scheduler-cell-sizes-vertical";
const HEADER_PANEL_CLASS = "dx-scheduler-header-panel";
const HEADER_PANEL_CELL_CLASS = "dx-scheduler-header-panel-cell";
const HEADER_ROW_CLASS = "dx-scheduler-header-row";
const GROUP_HEADER_CLASS = "dx-scheduler-group-header";
const DATE_TABLE_CELL_CLASS = "dx-scheduler-date-table-cell";
const DATE_TABLE_FOCUSED_CELL_CLASS = "dx-scheduler-focused-cell";
const VIRTUAL_ROW_CLASS = "dx-scheduler-virtual-row";
const DATE_TABLE_DROPPABLE_CELL_CLASS = "dx-scheduler-date-table-droppable-cell";
const SCHEDULER_HEADER_SCROLLABLE_CLASS = "dx-scheduler-header-scrollable";
const SCHEDULER_SIDEBAR_SCROLLABLE_CLASS = "dx-scheduler-sidebar-scrollable";
const SCHEDULER_DATE_TABLE_SCROLLABLE_CLASS = "dx-scheduler-date-table-scrollable";
const SCHEDULER_WORKSPACE_DXPOINTERDOWN_EVENT_NAME = addNamespace(pointerEvents.down, "dxSchedulerWorkSpace");
const DragEventNames = {
ENTER: addNamespace(dragEventEnter, "dxSchedulerDateTable"),
DROP: addNamespace(dragEventDrop, "dxSchedulerDateTable"),
LEAVE: addNamespace(dragEventLeave, "dxSchedulerDateTable")
};
const SCHEDULER_CELL_DXCLICK_EVENT_NAME = addNamespace(clickEventName, "dxSchedulerDateTable");
const SCHEDULER_CELL_DXPOINTERDOWN_EVENT_NAME = addNamespace(pointerEvents.down, "dxSchedulerDateTable");
const SCHEDULER_CELL_DXPOINTERUP_EVENT_NAME = addNamespace(pointerEvents.up, "dxSchedulerDateTable");
const SCHEDULER_CELL_DXPOINTERMOVE_EVENT_NAME = addNamespace(pointerEvents.move, "dxSchedulerDateTable");
const CELL_DATA = "dxCellData";
const DATE_TABLE_MIN_CELL_WIDTH = 75;
const DAY_MS = toMs("day");
const HOUR_MS = toMs("hour");
const DRAG_AND_DROP_SELECTOR = `.${DATE_TABLE_CLASS} td, .${ALL_DAY_TABLE_CLASS} td`;
const CELL_SELECTOR = `.${DATE_TABLE_CELL_CLASS}, .${ALL_DAY_TABLE_CELL_CLASS}`;
const CELL_INDEX_CALCULATION_EPSILON = .05;
const DEFAULT_WORKSPACE_RENDER_OPTIONS = {
renderComponents: {
header: true,
timePanel: true,
dateTable: true,
allDayPanel: true
},
generateNewData: true
};
class SchedulerWorkSpace extends Widget {
constructor() {
super(...arguments);
this.viewDirection = "vertical"
}
_activeStateUnit() {
return CELL_SELECTOR
}
get type() {
return ""
}
get viewDataProvider() {
if (!this.viewDataProviderValue) {
this.viewDataProviderValue = new ViewDataProvider(this.type)
}
return this.viewDataProviderValue
}
get cache() {
if (!this.cacheValue) {
this.cacheValue = new Cache
}
return this.cacheValue
}
get resourceManager() {
return this.option("getResourceManager")()
}
get cellsSelectionState() {
if (!this.cellsSelectionStateValue) {
this.cellsSelectionStateValue = new CellsSelectionState(this.viewDataProvider);
const selectedCellsOption = this.option("selectedCellData");
if ((null === selectedCellsOption || void 0 === selectedCellsOption ? void 0 : selectedCellsOption.length) > 0) {
const validSelectedCells = selectedCellsOption.map(selectedCell => {
const {
groups: groups
} = selectedCell;
if (!groups || 0 === this._getGroupCount()) {
return Object.assign({}, selectedCell, {
groupIndex: 0
})
}
const groupIndex = this.getGroupIndexByGroupValues(groups);
return Object.assign({}, selectedCell, {
groupIndex: groupIndex
})
});
this.cellsSelectionStateValue.setSelectedCellsByData(validSelectedCells)
}
}
return this.cellsSelectionStateValue
}
get cellsSelectionController() {
if (!this.cellsSelectionControllerValue) {
this.cellsSelectionControllerValue = new CellsSelectionController
}
return this.cellsSelectionControllerValue
}
get isAllDayPanelVisible() {
return this.isShowAllDayPanel() && this.supportAllDayRow()
}
get verticalGroupTableClass() {
return WORKSPACE_VERTICAL_GROUP_TABLE_CLASS
}
get renovatedHeaderPanelComponent() {
return HeaderPanelComponent
}
get timeZoneCalculator() {
return this.option("timeZoneCalculator")
}
get isDefaultDraggingMode() {
return "default" === this.option("draggingMode")
}
notifyObserver(funcName, args) {
this.invoke(funcName, ...args)
}
invoke(funcName) {
const notifyScheduler = this.option("notifyScheduler");
if (!notifyScheduler) {
return
}
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key]
}
return notifyScheduler.invoke(funcName, ...args)
}
_supportedKeys() {
const clickHandler = function(e) {
e.preventDefault();
e.stopPropagation();
const selectedCells = this.getSelectedCellsData();
if (null !== selectedCells && void 0 !== selectedCells && selectedCells.length) {
const selectedCellsElement = selectedCells.map(cellData => this.getCellByData(cellData)).filter(cell => Boolean(cell));
e.target = selectedCellsElement;
this.showPopup = true;
this.cellClickAction({
event: e,
cellElement: $(selectedCellsElement),
cellData: selectedCells[0]
})
}
};
const onArrowPressed = (e, key) => {
var _this$cellsSelectionS;
e.preventDefault();
e.stopPropagation();
const focusedCellData = null === (_this$cellsSelectionS = this.cellsSelectionState.getFocusedCell()) || void 0 === _this$cellsSelectionS ? void 0 : _this$cellsSelectionS.cellData;
if (focusedCellData) {
const isAllDayPanelCell = focusedCellData.allDay && !this.isVerticalGroupedWorkSpace();
const isMultiSelection = e.shiftKey;
const isMultiSelectionAllowed = this.option("allowMultipleCellSelection");
const isRTL = this.isRTL();
const groupCount = this._getGroupCount();
const isGroupedByDate = this.isGroupedByDate();
const isHorizontalGrouping = this._isHorizontalGroupedWorkSpace();
const focusedCellPosition = this.viewDataProvider.findCellPositionInMap(Object.assign({}, focusedCellData, {
isAllDay: focusedCellData.allDay
}));
const edgeIndices = isHorizontalGrouping && isMultiSelection && !isGroupedByDate ? this.viewDataProvider.getGroupEdgeIndices(focusedCellData.groupIndex, isAllDayPanelCell) : this.viewDataProvider.getViewEdgeIndices(isAllDayPanelCell);
const nextCellData = this.cellsSelectionController.handleArrowClick({
focusedCellPosition: focusedCellPosition,
edgeIndices: edgeIndices,
isRTL: isRTL,
isGroupedByDate: isGroupedByDate,
groupCount: groupCount,
isMultiSelection: isMultiSelection,
isMultiSelectionAllowed: isMultiSelectionAllowed,
viewType: this.type,
key: key,
getCellDataByPosition: this.viewDataProvider.getCellData.bind(this.viewDataProvider),
isAllDayPanelCell: isAllDayPanelCell,
focusedCellData: focusedCellData
});
this.processNextSelectedCell(nextCellData, focusedCellData, isMultiSelection && isMultiSelectionAllowed)
}
};
return extend(super._supportedKeys(), {
enter: clickHandler,
space: clickHandler,
downArrow: e => {
onArrowPressed(e, "down")
},
upArrow: e => {
onArrowPressed(e, "up")
},
rightArrow: e => {
onArrowPressed(e, "right")
},
leftArrow: e => {
onArrowPressed(e, "left")
}
})
}
isRTL() {
return this.option("rtlEnabled")
}
moveToCell($cell, isMultiSelection) {
if (!isDefined($cell) || !$cell.length) {
return
}
const isMultiSelectionAllowed = this.option("allowMultipleCellSelection");
const currentCellData = this.getFullCellData($cell);
const focusedCell = this.cellsSelectionState.getFocusedCell();
if (!focusedCell) {
return
}
const focusedCellData = focusedCell.cellData;
const nextFocusedCellData = this.cellsSelectionController.moveToCell({
isMultiSelection: isMultiSelection,
isMultiSelectionAllowed: isMultiSelectionAllowed,
currentCellData: currentCellData,
focusedCellData: focusedCellData,
isVirtualCell: $cell.hasClass(VIRTUAL_CELL_CLASS)
});
this.processNextSelectedCell(nextFocusedCellData, focusedCellData, isMultiSelectionAllowed && isMultiSelection)
}
processNextSelectedCell(nextCellData, focusedCellData, isMultiSelection) {
const nextCellPosition = this.viewDataProvider.findCellPositionInMap({
startDate: nextCellData.startDate,
groupIndex: nextCellData.groupIndex,
isAllDay: nextCellData.allDay,
index: nextCellData.index
});
if (!this.viewDataProvider.isSameCell(focusedCellData, nextCellData)) {
const $cell = nextCellData.allDay && !this.isVerticalGroupedWorkSpace() ? this.domGetAllDayPanelCell(nextCellPosition.columnIndex) : this.domGetDateCell(nextCellPosition);
const isNextCellAllDay = nextCellData.allDay;
this.setSelectedCellsStateAndUpdateSelection(isNextCellAllDay, nextCellPosition, isMultiSelection, $cell);
this._dateTableScrollable.scrollToElement($cell)
}
}
setSelectedCellsStateAndUpdateSelection(isAllDay, cellPosition, isMultiSelection, $nextFocusedCell) {
const nextCellCoordinates = {
rowIndex: cellPosition.rowIndex,
columnIndex: cellPosition.columnIndex,
allDay: isAllDay
};
this.cellsSelectionState.setFocusedCell(nextCellCoordinates.rowIndex, nextCellCoordinates.columnIndex, isAllDay);
if (isMultiSelection) {
this.cellsSelectionState.setSelectedCells(nextCellCoordinates)
} else {
this.cellsSelectionState.setSelectedCells(nextCellCoordinates, nextCellCoordinates)
}
this.updateCellsSelection();
this.updateSelectedCellDataOption(this.getSelectedCellsData(), $nextFocusedCell)
}
hasAllDayClass($cell) {
return $cell.hasClass(ALL_DAY_TABLE_CELL_CLASS)
}
_focusInHandler(e) {
const $target = $(e.target);
const $focusTarget = this._focusTarget();
const isTargetInsideWorkspace = $target.is($focusTarget) || $target.closest($focusTarget).length > 0;
if (isTargetInsideWorkspace && this.isCellClick) {
delete this.isCellClick;
delete this.contextMenuHandled;
super._focusInHandler.apply(this, arguments);
this.cellsSelectionState.restoreSelectedAndFocusedCells();
if (!this.cellsSelectionState.getFocusedCell()) {
const cellCoordinates = {
columnIndex: 0,
rowIndex: 0,
allDay: this.isVerticalGroupedWorkSpace() && this.isAllDayPanelVisible
};
this.cellsSelectionState.setFocusedCell(cellCoordinates.rowIndex, cellCoordinates.columnIndex, cellCoordinates.allDay);
this.cellsSelectionState.setSelectedCells(cellCoordinates, cellCoordinates)
}
this.updateCellsSelection();
this.updateSelectedCellDataOption(this.getSelectedCellsData())
}
}
_focusOutHandler() {
super._focusOutHandler.apply(this, arguments);
if (!this.contextMenuHandled && !this._disposed) {
this.cellsSelectionState.releaseSelectedAndFocusedCells();
this.viewDataProvider.updateViewData(this.generateRenderOptions());
this.updateCellsSelection()
}
}
_focusTarget() {
return this.$element()
}
isVerticalGroupedWorkSpace() {
var _this$option;
return Boolean(null === (_this$option = this.option("groups")) || void 0 === _this$option ? void 0 : _this$option.length) && "vertical" === this.option("groupOrientation")
}
_isHorizontalGroupedWorkSpace() {
var _this$option2;
return Boolean(null === (_this$option2 = this.option("groups")) || void 0 === _this$option2 ? void 0 : _this$option2.length) && "horizontal" === this.option("groupOrientation")
}
isWorkSpaceWithCount() {
return this.option("intervalCount") > 1
}
isWorkspaceWithOddCells() {
return .5 === this.option("hoursInterval") && !this.isVirtualScrolling()
}
getRealGroupOrientation() {
return this.isVerticalGroupedWorkSpace() ? "vertical" : "horizontal"
}
createRAllDayPanelElements() {
this._$allDayPanel = $("<div>").addClass(ALL_DAY_PANEL_CLASS);
this.$allDayTitle = $("<div>").appendTo(this.$headerPanelEmptyCell)
}
dateTableScrollableConfig() {
let config = {
useKeyboard: false,
bounceEnabled: false,
updateManually: true,
onScroll: () => {
var _this$_groupedStrateg;
null === (_this$_groupedStrateg = this._groupedStrategy.cache) || void 0 === _this$_groupedStrateg || _this$_groupedStrateg.clear()
},
onInitialized: _ref => {
let {
component: component
} = _ref;
const useKeyboardDisabled = false === component.option("useKeyboard");
const useNativeEnabled = true === component.option("useNative");
if (useKeyboardDisabled && useNativeEnabled) {
$(component.container()).attr("tabindex", -1)
}
},
onOptionChanged: _ref2 => {
let {
fullName: fullName,
value: value,
component: component
} = _ref2;
const useKeyboardDisabled = false === component.option("useKeyboard");
if (useKeyboardDisabled && "useNative" === fullName && true === value) {
$(component.container()).attr("tabindex", -1)
}
}
};
if (this.needCreateCrossScrolling()) {
config = extend(config, this.createCrossScrollingConfig(config))
}
if (this.isVirtualScrolling() && (this.virtualScrollingDispatcher.horizontalScrollingAllowed || this.virtualScrollingDispatcher.height)) {
const currentOnScroll = config.onScroll;
config = Object.assign({}, config, {
onScroll: e => {
null === currentOnScroll || void 0 === currentOnScroll || currentOnScroll(e);
this.virtualScrollingDispatcher.handleOnScrollEvent(null === e || void 0 === e ? void 0 : e.scrollOffset)
}
})
}
return config
}
createCrossScrollingConfig(_ref3) {
let {
onScroll: onScroll
} = _ref3;
return {
direction: "both",
onScroll: event => {
null === onScroll || void 0 === onScroll || onScroll();
this.scrollSync.sidebar({
top: event.scrollOffset.top
});
this.scrollSync.header({
left: event.scrollOffset.left
})
},
onEnd: () => {
this.option("onScrollEnd")()
}
}
}
headerScrollableConfig() {
return {
useKeyboard: false,
showScrollbar: "never",
direction: "horizontal",
useNative: false,
updateManually: true,
bounceEnabled: false,
onScroll: event => {
this.scrollSync.dateTable({
left: event.scrollOffset.left
})
}
}
}
_visibilityChanged(visible) {
this.cache.clear();
if (visible) {
this.updateGroupTableHeight()
}
if (visible && this.needCreateCrossScrolling()) {
this.setTableSizes()
}
}
setTableSizes() {
this.cache.clear();
this.attachTableClasses();
let cellWidth = this.getCellWidth();
if (cellWidth < this.getCellMinWidth()) {
cellWidth = this.getCellMinWidth()
}
const minWidth = this.getWorkSpaceMinWidth();
const groupCount = this._getGroupCount();
const totalCellCount = this.getTotalCellCount(groupCount);
let width = cellWidth * totalCellCount;
if (width < minWidth) {
width = minWidth
}
setWidth(this._$headerPanel, width);
setWidth(this._$dateTable, width);
if (this.$allDayTable) {
setWidth(this.$allDayTable, width)
}
this.attachHeaderTableClasses();
this.updateGroupTableHeight();
this.updateScrollable()
}
getWorkSpaceMinWidth() {
return this._groupedStrategy.getWorkSpaceMinWidth()
}
_dimensionChanged() {
if (!this._isVisible()) {
return
}
if (this.option("crossScrollingEnabled")) {
this.setTableSizes()
}
this.updateHeaderEmptyCellWidth();
this.updateScrollable();
this.cache.clear()
}
needCreateCrossScrolling() {
return this.option("crossScrollingEnabled")
}
getElementClass() {
return noop()
}
getRowCount() {
return this.viewDataProvider.getRowCount({
intervalCount: this.option("intervalCount"),
currentDate: this.option("currentDate"),
viewType: this.type,
hoursInterval: this.option("hoursInterval"),
startDayHour: this.option("startDayHour"),
endDayHour: this.option("endDayHour")
})
}
_getCellCount() {
return this.viewDataProvider.getCellCount({
intervalCount: this.option("intervalCount"),
currentDate: this.option("currentDate"),
viewType: this.type,
hoursInterval: this.option("hoursInterval"),
startDayHour: this.option("startDayHour"),
endDayHour: this.option("endDayHour")
})
}
isRenovatedRender() {
return this.renovatedRenderSupported() && this.option("renovateRender")
}
isVirtualModeOn() {
return "virtual" === this.option("scrolling.mode")
}
isVirtualScrolling() {
return this.isRenovatedRender() && this.isVirtualModeOn()
}
initVirtualScrolling() {
if (this.virtualScrollingDispatcher) {
this.virtualScrollingDispatcher.dispose();
this.virtualScrollingDispatcher = null
}
this.virtualScrollingDispatcher = new VirtualScrollingDispatcher(this.getVirtualScrollingDispatcherOptions());
this.virtualScrollingDispatcher.attachScrollableEvents();
this.renderer = new VirtualScrollingRenderer(this)
}
isGroupedAllDayPanel() {
return calculateIsGroupedAllDayPanel(this.option("groups").length, this.option("groupOrientation"), this.isAllDayPanelVisible)
}
generateRenderOptions(isProvideVirtualCellsWidth) {
var _this$getToday;
const groupCount = this._getGroupCount();
const groupOrientation = groupCount > 0 ? this.option("groupOrientation") : this.getDefaultGroupStrategy();
const options = Object.assign({
groupByDate: this.option("groupByDate"),
startRowIndex: 0,
startCellIndex: 0,
groupOrientation: groupOrientation,
today: null === (_this$getToday = this.getToday) || void 0 === _this$getToday ? void 0 : _this$getToday.call(this),
getResourceManager: this.option("getResourceManager"),
isProvideVirtualCellsWidth: isProvideVirtualCellsWidth,
isAllDayPanelVisible: this.isAllDayPanelVisible,
selectedCells: this.cellsSelectionState.getSelectedCells(),
focusedCell: this.cellsSelectionState.getFocusedCell(),
headerCellTextFormat: this.getFormat(),
getDateForHeaderText: (_, date) => date,
viewOffset: this.option("viewOffset"),
startDayHour: this.option("startDayHour"),
endDayHour: this.option("endDayHour"),
cellDuration: this.getCellDuration(),
viewType: this.type,
intervalCount: this.option("intervalCount"),
hoursInterval: this.option("hoursInterval"),
currentDate: this.option("currentDate"),
startDate: this.option("startDate"),
firstDayOfWeek: this.option("firstDayOfWeek"),
showCurrentTimeIndicator: this.option("showCurrentTimeIndicator")
}, this.virtualScrollingDispatcher.getRenderState());
return options
}
renovatedRenderSupported() {
return true
}
updateGroupTableHeight() {
if (this.isVerticalGroupedWorkSpace() && hasWindow()) {
this.setHorizontalGroupHeaderCellsHeight()
}
}
updateHeaderEmptyCellWidth() {
if (hasWindow() && this.isRenderHeaderPanelEmptyCell()) {
const timePanelWidth = this.getTimePanelWidth();
const groupPanelWidth = this.getGroupTableWidth();
this.$headerPanelEmptyCell.css("width", timePanelWidth + groupPanelWidth)
}
}
updateHeaderPanelScrollbarPadding() {
if (hasWindow() && this._$headerPanelContainer) {
const scrollbarWidth = this.getScrollbarWidth();
this._$headerPanelContainer.css("paddingRight", `${scrollbarWidth}px`)
}
}
getScrollbarWidth() {
const containerElement = $(this._dateTableScrollable.container()).get(0);
const scrollbarWidth = containerElement.offsetWidth - containerElement.clientWidth;
return scrollbarWidth
}
isGroupsSpecified(groupValues) {
var _this$option3;
return (null === (_this$option3 = this.option("groups")) || void 0 === _this$option3 ? void 0 : _this$option3.length) && groupValues
}
getGroupIndexByGroupValues(groupValues) {
return groupValues && getAppointmentGroupIndex(getSafeGroupValues(groupValues), this.resourceManager.groupsLeafs)[0]
}
getViewStartByOptions() {
return getViewStartByOptions(this.option("startDate"), this.option("currentDate"), this.getTotalViewDuration(), this.option("startDate") ? this.calculateViewStartDate() : void 0)
}
getTotalViewDuration() {
return this.viewDataProvider.getIntervalDuration(this.option("intervalCount"))
}
getHeaderDate() {
return this.getStartViewDate()
}
calculateViewStartDate() {
return calculateViewStartDate(this.option("startDate"))
}
firstDayOfWeek() {
return this.viewDataProvider.getFirstDayOfWeek(this.option("firstDayOfWeek"))
}
attachEvents() {
this.createSelectionChangedAction();
this.attachClickEvent();
this.attachContextMenuEvent()
}
attachClickEvent() {
const that = this;
const pointerDownAction = this._createAction(e => {
that.pointerDownHandler(e.event)
});
this.createCellClickAction();
const cellSelector = `.${DATE_TABLE_CELL_CLASS},.${ALL_DAY_TABLE_CELL_CLASS}`;
const $element = this.$element();
eventsEngine.off($element, SCHEDULER_WORKSPACE_DXPOINTERDOWN_EVENT_NAME);
eventsEngine.off($element, SCHEDULER_CELL_DXCLICK_EVENT_NAME);
eventsEngine.on($element, SCHEDULER_WORKSPACE_DXPOINTERDOWN_EVENT_NAME, e => {
if (isMouseEvent(e) && e.which > 1) {
e.preventDefault();
return
}
pointerDownAction({
event: e
})
});
eventsEngine.on($element, SCHEDULER_CELL_DXCLICK_EVENT_NAME, cellSelector, e => {
const $cell = $(e.target);
that.cellClickAction({
event: e,
cellElement: getPublicElement($cell),
cellData: that.getCellData($cell)
})
})
}
createCellClickAction() {
this.cellClickAction = this._createActionByOption("onCellClick", {
afterExecute: e => this.cellClickHandler(e.args[0].event)
})
}
createSelectionChangedAction() {
this.selectionChangedAction = this._createActionByOption("onSelectionChanged")
}
cellClickHandler(argument) {
if (this.showPopup) {
delete this.showPopup;
this.handleSelectedCellsClick()
}
}
pointerDownHandler(e) {
const $target = $(e.target);
if (!$target.hasClass(DATE_TABLE_CELL_CLASS) && !$target.hasClass(ALL_DAY_TABLE_CELL_CLASS)) {
this.isCellClick = false;
return
}
this.isCellClick = true;
if ($target.hasClass("dx-scheduler-focused-cell")) {
this.showPopup = true
} else {
const cellCoordinates = this.getCoordinatesByCell($target);
const isAllDayCell = this.hasAllDayClass($target);
this.setSelectedCellsStateAndUpdateSelection(isAllDayCell, cellCoordinates, false, $target)
}
}
handleSelectedCellsClick() {
const selectedCells = this.getSelectedCellsData();
const firstCellData = selectedCells[0];
const lastCellData = selectedCells[selectedCells.length - 1];
const result = {
startDate: firstCellData.startDate,
endDate: lastCellData.endDate,
startDateUTC: firstCellData.startDateUTC,
endDateUTC: lastCellData.endDateUTC
};
if (void 0 !== lastCellData.allDay) {
result.allDay = lastCellData.allDay
}
this.option("onSelectedCellsClick")(result, lastCellData.groups)
}
attachContextMenuEvent() {
this.createContextMenuAction();
const cellSelector = `.${DATE_TABLE_CELL_CLASS},.${ALL_DAY_TABLE_CELL_CLASS}`;
const $element = this.$element();
const eventName = addNamespace(contextMenuEventName, this.NAME);
eventsEngine.off($element, eventName, cellSelector);
eventsEngine.on($element, eventName, cellSelector, this.contextMenuHandler.bind(this))
}
contextMenuHandler(e) {
const $cell = $(e.target);
this.contextMenuAction({
event: e,
cellElement: getPublicElement($cell),
cellData: this.getCellData($cell)
});
this.contextMenuHandled = true
}
createContextMenuAction() {
this.contextMenuAction = this._createActionByOption("onCellContextMenu")
}
getGroupHeaderContainer() {
if (this.isVerticalGroupedWorkSpace()) {
return this._$groupTable
}
return this._$thead
}
getDateHeaderContainer() {
return this._$thead
}
getCalculateHeaderCellRepeatCount() {
return this._groupedStrategy.calculateHeaderCellRepeatCount()
}
updateScrollable() {
var _this$headerScrollabl, _this$_sidebarScrolla;
this._dateTableScrollable.update();
null === (_this$headerScrollabl = this.headerScrollable) || void 0 === _this$headerScrollabl || _this$headerScrollabl.update();
null === (_this$_sidebarScrolla = this._sidebarScrollable) || void 0 === _this$_sidebarScrolla || _this$_sidebarScrolla.update();
this.updateHeaderPanelScrollbarPadding()
}
getTimePanelRowCount() {
return this.getCellCountInDay()
}
getCellCountInDay() {
const hoursInterval = this.option("hoursInterval");
const startDayHour = this.option("startDayHour");
const endDayHour = this.option("endDayHour");
return this.viewDataProvider.getCellCountInDay(startDayHour, endDayHour, hoursInterval)
}
getTotalCellCount(groupCount) {
return this._groupedStrategy.getTotalCellCount(groupCount)
}
getTotalRowCount(groupCount, includeAllDayPanelRows) {
let result = this._groupedStrategy.getTotalRowCount(groupCount);
if (includeAllDayPanelRows && this.isAllDayPanelVisible) {
result += groupCount
}
return result
}
getGroupIndex(rowIndex, columnIndex) {
return this._groupedStrategy.getGroupIndex(rowIndex, columnIndex)
}
calculateEndDate(startDate) {
const {
viewDataGenerator: viewDataGenerator
} = this.viewDataProvider;
return viewDataGenerator.calculateEndDate(startDate, viewDataGenerator.getInterval(this.option("hoursInterval")), this.option("endDayHour"))
}
_getGroupCount() {
return this.resourceManager.groupCount()
}
attachTablesEvents() {
const element = this.$element();
this.attachDragEvents(element);
this.attachPointerEvents(element)
}
detachDragEvents(element) {
eventsEngine.off(element, DragEventNames.ENTER);
eventsEngine.off(element, DragEventNames.LEAVE);
eventsEngine.off(element, DragEventNames.DROP)
}
attachDragEvents(element) {
this.detachDragEvents(element);
eventsEngine.on(element, DragEventNames.ENTER, DRAG_AND_DROP_SELECTOR, {
checkDropTarget: (target, event) => !this.isOutsideScrollable(target, event)
}, e => {
if (!this.preventDefaultDragging) {
this.removeDroppableCellClass();
$(e.target).addClass(DATE_TABLE_DROPPABLE_CELL_CLASS)
}
});
eventsEngine.on(element, DragEventNames.LEAVE, () => {
if (!this.preventDefaultDragging) {
this.removeDroppableCellClass()
}
});
eventsEngine.on(element, DragEventNames.DROP, DRAG_AND_DROP_SELECTOR, () => {
var _this$dragBehavior, _this$dragBehavior$dr;
if (!this.dragBehavior) {
return
}
if (!(null !== (_this$dragBehavior = this.dragBehavior) && void 0 !== _this$dragBehavior && _this$dragBehavior.dragBetweenComponentsPromise)) {
this.dragBehavior.removeDroppableClasses();
return
}
null === (_this$dragBehavior$dr = this.dragBehavior.dragBetweenComponentsPromise) || void 0 === _this$dragBehavior$dr || _this$dragBehavior$dr.then(() => {
this.dragBehavior.removeDroppableClasses()
})
})
}
attachPointerEvents(element) {
let isPointerDown = false;
eventsEngine.off(element, SCHEDULER_CELL_DXPOINTERMOVE_EVENT_NAME);
eventsEngine.off(element, SCHEDULER_CELL_DXPOINTERDOWN_EVENT_NAME);
eventsEngine.on(element, SCHEDULER_CELL_DXPOINTERDOWN_EVENT_NAME, DRAG_AND_DROP_SELECTOR, e => {
if (isMouseEvent(e) && 1 === e.which) {
isPointerDown = true;
this.$element().addClass(WORKSPACE_WITH_MOUSE_SELECTION_CLASS);
eventsEngine.off(domAdapter.getDocument(), SCHEDULER_CELL_DXPOINTERUP_EVENT_NAME);
eventsEngine.on(domAdapter.getDocument(), SCHEDULER_CELL_DXPOINTERUP_EVENT_NAME, () => {
isPointerDown = false;
this.$element().removeClass(WORKSPACE_WITH_MOUSE_SELECTION_CLASS)
})
}
});
eventsEngine.on(element, SCHEDULER_CELL_DXPOINTERMOVE_EVENT_NAME, DRAG_AND_DROP_SELECTOR, e => {
if (isPointerDown && this._dateTableScrollable && !this._dateTableScrollable.option("scrollByContent")) {
e.preventDefault();
e.stopPropagation();
this.moveToCell($(e.target), true)
}
})
}
getFormat() {
return abstract()
}
getWorkArea() {
return this.$dateTableContainer
}
getScrollable() {
return this._dateTableScrollable
}
getScrollableScrollTop() {
return this._dateTableScrollable.scrollTop()
}
getGroupedScrollableScrollTop(allDay) {
return this._groupedStrategy.getScrollableScrollTop(allDay)
}
getScrollableScrollLeft() {
return this._dateTableScrollable.scrollLeft()
}
getScrollableOuterWidth() {
return this._dateTableScrollable.scrollWidth()
}
getScrollableContainer() {
return $(this._dateTableScrollable.container())
}
getHeaderPanelHeight() {
return this._$headerPanel && getOuterHeight(this._$headerPanel, true)
}
getTimePanelWidth() {
return this.$timePanel && getBoundingRect(this.$timePanel.get(0)).width
}
getGroupTableWidth() {
return this._$groupTable ? getOuterWidth(this._$groupTable) : 0
}
getWorkSpaceLeftOffset() {
return this._groupedStrategy.getLeftOffset()
}
getCellCoordinatesByIndex(index) {
const columnIndex = Math.floor(index / this.getRowCount());
const rowIndex = index - this.getRowCount() * columnIndex;
return {
columnIndex: columnIndex,
rowIndex: rowIndex
}
}
getDateGenerationOptions() {
var _this$viewDataProvide;
return {
startDayHour: this.option("startDayHour"),
endDayHour: this.option("endDayHour"),
interval: null === (_this$viewDataProvide = this.viewDataProvider.viewDataGenerator) || void 0 === _this$viewDataProvide ? void 0 : _this$viewDataProvide.getInterval(this.option("hoursInterval")),
startViewDate: this.getStartViewDate(),
firstDayOfWeek: this.firstDayOfWeek()
}
}
getIntervalBetween(currentDate, allDay) {
const firstViewDate = this.getStartViewDate();
const startDayTime = this.option("startDayHour") * HOUR_MS;
const timeZoneOffset = dateUtils.getTimezonesDifference(firstViewDate, currentDate);
const fullInterval = currentDate.getTime() - firstViewDate.getTime() - timeZoneOffset;
const days = this.getDaysOfInterval(fullInterval, startDayTime);
const weekendsCount = this.getWeekendsCount(days);
let result = (days - weekendsCount) * DAY_MS;
if (!allDay) {
const {
hiddenInterval: hiddenInterval
} = this.viewDataProvider;
const visibleDayDuration = this.getVisibleDayDuration();
result = fullInterval - days * hiddenInterval - weekendsCount * visibleDayDuration
}
return result
}
getWeekendsCount(argument) {
return 0
}
getDaysOfInterval(fullInterval, startDayTime) {
return Math.floor((fullInterval + startDayTime) / DAY_MS)
}
updateIndex(index) {
return index * this.getRowCount()
}
getDroppableCell() {
return this.getDateTables().find(`.${DATE_TABLE_DROPPABLE_CELL_CLASS}`)
}
getWorkSpaceWidth() {
return this.cache.memo("workspaceWidth", () => {
if (this.needCreateCrossScrolling()) {
return getBoundingRect(this._$dateTable.get(0)).width
}
const totalWidth = getBoundingRect(this.$element().get(0)).width;
const timePanelWidth = this.getTimePanelWidth();
const groupTableWidth = this.getGroupTableWidth();
return totalWidth - timePanelWidth - groupTableWidth
})
}
getCellElementByPosition(cellCoordinates, groupIndex, inAllDayRow) {
const indexes = this._groupedStrategy.prepareCellIndexes(cellCoordinates, groupIndex, inAllDayRow);
return this.domGetDateCell(indexes)
}
domGetDateCell(position) {
return this._$dateTable.find(`tr:not(.${VIRTUAL_ROW_CLASS})`).eq(position.rowIndex).find(`td:not(.${VIRTUAL_CELL_CLASS})`).eq(position.columnIndex)
}
domGetAllDayPanelCell(columnIndex) {
return this._$allDayPanel.find("tr").eq(0).find("td").eq(columnIndex)
}
getCells(allDay, direction) {
const cellClass = allDay ? ALL_DAY_TABLE_CELL_CLASS : DATE_TABLE_CELL_CLASS;
if ("vertical" === direction) {
let result = [];
for (let i = 1;; i++) {
const cells = this.$element().find(`tr .${cellClass}:nth-child(${i})`);
if (!cells.length) {
break
}
result = result.concat(cells.toArray())
}
return $(result)
}
return this.$element().find(`.${cellClass}`)
}
getFirstAndLastDataTableCell() {
const selector = this.isVirtualScrolling() ? `.${DATE_TABLE_CELL_CLASS}, .${VIRTUAL_CELL_CLASS}` : `.${DATE_TABLE_CELL_CLASS}`;
const $cells = this.$element().find(selector);
return [$cells[0], $cells[$cells.length - 1]]
}
getAllCells(allDay) {
if (this.isVerticalGroupedWorkSpace()) {
return this._$dateTable.find(`td:not(.${VIRTUAL_CELL_CLASS})`)
}
const cellClass = allDay && this.supportAllDayRow() ? ALL_DAY_TABLE_CELL_CLASS : DATE_TABLE_CELL_CLASS;
return this.$element().find(`.${cellClass}`)
}
setHorizontalGroupHeaderCellsHeight() {
const {
height: height
} = getBoundingRect(this._$dateTable.get(0));
setOuterHeight(this._$groupTable, height)
}
getGroupHeaderCells() {
return this.$element().find(`.${GROUP_HEADER_CLASS}`)
}
getScrollCoordinates(date, groupIndex, allDay) {
const currentDate = date || new Date(this.option("currentDate"));
const cell = this.viewDataProvider.findGlobalCellPosition(currentDate, groupIndex, allDay, true);
if (!cell) {
return
}
currentDate.setHours(cell.cellData.startDate.getHours(), currentDate.getMinutes(), 0, 0);
return this.virtualScrollingDispatcher.calculateCoordinatesByDataAndPosition(cell.cellData, cell.position, currentDate, isDateAndTimeView(this.type), "vertical" === this.viewDirection)
}
isOutsideScrollable(target, event) {
const $dateTableScrollableElement = this._dateTableScrollable.$element();
const scrollableSize = getBoundingRect($dateTableScrollableElement.get(0));
const window = getWindow();
const isTargetInAllDayPanel = !$(target).closest($dateTableScrollableElement).length;
const isOutsideHorizontalScrollable = event.pageX < scrollableSize.left || event.pageX > scrollableSize.left + scrollableSize.width + (window.scrollX || 0);
const isOutsideVerticalScrollable = event.pageY < scrollableSize.top || event.pageY > scrollableSize.top + scrollableSize.height + (window.scrollY || 0);
if (isTargetInAllDayPanel && !isOutsideHorizontalScrollable) {
return false
}
return isOutsideVerticalScrollable || isOutsideHorizontalScrollable
}
supportAllDayRow() {
return true
}
keepOriginalHours() {
return false
}
normalizeCellData(cellData) {
var _this$timeZoneCalcula, _this$timeZoneCalcula2;
return extend(true, {}, {
startDate: cellData.startDate,
endDate: cellData.endDate,
startDateUTC: cellData.startDate && (null === (_this$timeZoneCalcula = this.timeZoneCalculator) || void 0 === _this$timeZoneCalcula ? void 0 : _this$timeZoneCalcula.createDate(cellData.startDate, "fromGrid")),
endDateUTC: cellData.endDate && (null === (_this$timeZoneCalcula2 = this.timeZoneCalculator) || void 0 === _this$timeZoneCalcula2 ? void 0 : _this$timeZoneCalcula2.createDate(cellData.endDate, "fromGrid")),
groups: cellData.groups,
groupIndex: cellData.groupIndex,
allDay: cellData.allDay
})
}
getSelectedCellsData() {
const selected = this.cellsSelectionState.getSelectedCells();
return null === selected || void 0 === selected ? void 0 : selected.map(this.normalizeCellData.bind(this))
}
getCellData($cell) {
const cellData = this.getFullCellData($cell) ?? {};
return this.normalizeCellData(cellData)
}
getFullCellData($cell) {
const currentCell = $cell[0];
if (currentCell) {
return this.getDataByCell($cell)
}
return
}
getVirtualRowOffset() {
return this.virtualScrollingDispatcher.virtualRowOffset
}
getVirtualCellOffset() {
return this.virtualScrollingDispatcher.virtualCellOffset
}
getDataByCell($cell) {
const rowIndex = $cell.parent().index() - this.virtualScrollingDispatcher.topVirtualRowsCount;
const columnIndex = $cell.index() - this.virtualScrollingDispatcher.leftVirtualCellsCount;
const {
viewDataProvider: viewDataProvider
} = this;
const isAllDayCell = this.hasAllDayClass($cell);
const cellData = viewDataProvider.getCellData(rowIndex, columnIndex, isAllDayCell);
return cellData || void 0
}
isGroupedByDate() {
return this.option("groupByDate") && this._isHorizontalGroupedWorkSpace() && this._getGroupCount() > 0
}
getCellIndexByDate(date, inAllDayRow) {
const {
viewDataGenerator: viewDataGenerator
} = this.viewDataProvider;
const timeInterval = inAllDayRow ? 864e5 : viewDataGenerator.getInterval(this.option("hoursInterval"));
const startViewDateOffset = getStartViewDateTimeOffset(this.getStartViewDate(), this.option("startDayHour"));
const dateTimeStamp = this.getIntervalBetween(date, inAllDayRow) + startViewDateOffset;
let index = Math.floor(dateTimeStamp / timeInterval);
if (inAllDayRow) {
index = this.updateIndex(index)
}
if (index < 0) {
index = 0
}
return index
}
getDataByDroppableCell() {
const cellData = this.getCellData($(this.getDroppableCell()));
const {
allDay: allDay
} = cellData;
const {
startDate: startDate
} = cellData;
const {
endDate: endDate
} = cellData;
return {
startDate: startDate,
endDate: endDate,
allDay: allDay,
groups: cellData.groups
}
}
getDateRange() {
return [this.getStartViewDate(), this.