| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467 |
- /**
- * DevExtreme (ui/scheduler/workspaces/ui.scheduler.timeline.js)
- * Version: 19.1.16
- * Build date: Tue Oct 18 2022
- *
- * Copyright (c) 2012 - 2022 Developer Express Inc. ALL RIGHTS RESERVED
- * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
- */
- "use strict";
- var $ = require("../../../core/renderer");
- var noop = require("../../../core/utils/common").noop;
- var extend = require("../../../core/utils/extend").extend;
- var registerComponent = require("../../../core/component_registrator");
- var SchedulerWorkSpace = require("./ui.scheduler.work_space.indicator");
- var dateUtils = require("../../../core/utils/date");
- var tableCreator = require("../ui.scheduler.table_creator");
- var HorizontalShader = require("../shaders/ui.scheduler.current_time_shader.horizontal");
- var TIMELINE_CLASS = "dx-scheduler-timeline";
- var GROUP_TABLE_CLASS = "dx-scheduler-group-table";
- var HORIZONTAL_GROUPED_WORKSPACE_CLASS = "dx-scheduler-work-space-horizontal-grouped";
- var HEADER_PANEL_CELL_CLASS = "dx-scheduler-header-panel-cell";
- var HEADER_PANEL_WEEK_CELL_CLASS = "dx-scheduler-header-panel-week-cell";
- var HEADER_ROW_CLASS = "dx-scheduler-header-row";
- var HORIZONTAL = "horizontal";
- var DATE_TABLE_CELL_BORDER = 1;
- var DATE_TABLE_HEADER_MARGIN = 10;
- var toMs = dateUtils.dateToMilliseconds;
- var SchedulerTimeline = SchedulerWorkSpace.inherit({
- _init: function() {
- this.callBase();
- this.$element().addClass(TIMELINE_CLASS);
- this._$sidebarTable = $("<table>").addClass(GROUP_TABLE_CLASS)
- },
- _getCellFromNextRow: function(direction, isMultiSelection) {
- if (!isMultiSelection) {
- return this.callBase(direction, isMultiSelection)
- }
- return this._$focusedCell
- },
- _getDefaultGroupStrategy: function() {
- return "vertical"
- },
- _toggleGroupingDirectionClass: function() {
- this.$element().toggleClass(HORIZONTAL_GROUPED_WORKSPACE_CLASS, this._isHorizontalGroupedWorkSpace())
- },
- _getDefaultOptions: function() {
- return extend(this.callBase(), {
- groupOrientation: "vertical"
- })
- },
- _getRightCell: function() {
- var $rightCell;
- var $focusedCell = this._$focusedCell;
- var rowCellCount = this._getCellCount();
- var edgeCellIndex = this._isRTL() ? 0 : rowCellCount - 1;
- var direction = this._isRTL() ? "prev" : "next";
- if ($focusedCell.index() === edgeCellIndex) {
- $rightCell = $focusedCell
- } else {
- $rightCell = $focusedCell[direction]();
- $rightCell = this._checkForViewBounds($rightCell)
- }
- return $rightCell
- },
- _getLeftCell: function() {
- var $leftCell;
- var $focusedCell = this._$focusedCell;
- var rowCellCount = this._getCellCount();
- var edgeCellIndex = this._isRTL() ? rowCellCount - 1 : 0;
- var direction = this._isRTL() ? "next" : "prev";
- if ($focusedCell.index() === edgeCellIndex) {
- $leftCell = $focusedCell
- } else {
- $leftCell = $focusedCell[direction]();
- $leftCell = this._checkForViewBounds($leftCell)
- }
- return $leftCell
- },
- _getRowCount: function() {
- return 1
- },
- _getCellCount: function() {
- return this._getCellCountInDay() * this.option("intervalCount")
- },
- getGroupTableWidth: function() {
- return this._$sidebarTable ? this._$sidebarTable.outerWidth() : 0
- },
- _getTotalRowCount: function(groupCount) {
- if (this._isHorizontalGroupedWorkSpace()) {
- return this._getRowCount()
- } else {
- groupCount = groupCount || 1;
- return this._getRowCount() * groupCount
- }
- },
- _getDateByIndex: function(index) {
- var resultDate = new Date(this._firstViewDate);
- var dayIndex = Math.floor(index / this._getCellCountInDay());
- resultDate.setTime(this._firstViewDate.getTime() + this._calculateCellIndex(0, index) * this._getInterval() + dayIndex * this._getHiddenInterval());
- return resultDate
- },
- _getFormat: function() {
- return "shorttime"
- },
- _needApplyLastGroupCellClass: function() {
- return true
- },
- _calculateHiddenInterval: function(rowIndex, cellIndex) {
- var dayIndex = Math.floor(cellIndex / this._getCellCountInDay());
- return dayIndex * this._getHiddenInterval()
- },
- _getMillisecondsOffset: function(rowIndex, cellIndex) {
- cellIndex = this._calculateCellIndex(rowIndex, cellIndex);
- return this._getInterval() * cellIndex + this._calculateHiddenInterval(rowIndex, cellIndex)
- },
- _createWorkSpaceElements: function() {
- this._createWorkSpaceScrollableElements()
- },
- _getWorkSpaceHeight: function() {
- if (this.option("crossScrollingEnabled")) {
- return this._$dateTable.get(0).getBoundingClientRect().height
- }
- return this.$element().get(0).getBoundingClientRect().height
- },
- _dateTableScrollableConfig: function() {
- var config = this.callBase();
- var timelineConfig = {
- direction: HORIZONTAL
- };
- return this.option("crossScrollingEnabled") ? config : extend(config, timelineConfig)
- },
- _needCreateCrossScrolling: function() {
- return true
- },
- _headerScrollableConfig: function() {
- var config = this.callBase();
- return extend(config, {
- scrollByContent: true
- })
- },
- _renderTimePanel: noop,
- _renderAllDayPanel: noop,
- _getTableAllDay: function() {
- return false
- },
- _getDateHeaderTemplate: function() {
- return this.option("timeCellTemplate")
- },
- _toggleAllDayVisibility: noop,
- _changeAllDayVisibility: noop,
- supportAllDayRow: function() {
- return false
- },
- _getGroupHeaderContainer: function() {
- if (this._isHorizontalGroupedWorkSpace()) {
- return this._$thead
- }
- return this._$sidebarTable
- },
- _insertAllDayRowsIntoDateTable: function() {
- return false
- },
- _createAllDayPanelElements: noop,
- _renderDateHeader: function() {
- var $headerRow = this.callBase();
- if (this._needRenderWeekHeader()) {
- var firstViewDate = new Date(this._firstViewDate);
- var $cells = [];
- var colspan = this._getCellCountInDay();
- var cellTemplate = this.option("dateCellTemplate");
- for (var i = 0; i < this._getWeekDuration() * this.option("intervalCount"); i++) {
- var $th = $("<th>");
- var text = this._formatWeekdayAndDay(firstViewDate);
- if (cellTemplate) {
- var templateOptions = {
- model: {
- text: text,
- date: new Date(firstViewDate)
- },
- container: $th,
- index: i
- };
- cellTemplate.render(templateOptions)
- } else {
- $th.text(text)
- }
- $th.addClass(HEADER_PANEL_CELL_CLASS).addClass(HEADER_PANEL_WEEK_CELL_CLASS).attr("colSpan", colspan);
- $cells.push($th);
- this._incrementDate(firstViewDate)
- }
- var $row = $("<tr>").addClass(HEADER_ROW_CLASS).append($cells);
- $headerRow.before($row)
- }
- },
- _needRenderWeekHeader: function() {
- return false
- },
- _incrementDate: function(date) {
- date.setDate(date.getDate() + 1)
- },
- _getWeekDuration: function() {
- return 1
- },
- _renderView: function() {
- this._setFirstViewDate();
- var groupCellTemplates = this._renderGroupHeader();
- this._renderDateHeader();
- this._renderAllDayPanel();
- this._renderTimePanel();
- this._renderDateTable();
- this._shader = new HorizontalShader;
- this._updateGroupTableHeight();
- this._$sidebarTable.appendTo(this._sidebarScrollable.$content());
- this._applyCellTemplates(groupCellTemplates)
- },
- _setHorizontalGroupHeaderCellsHeight: noop,
- getIndicationWidth: function() {
- var today = this._getToday();
- var cellWidth = this.getCellWidth();
- var date = this._getIndicationFirstViewDate();
- var hiddenInterval = this._getHiddenInterval();
- var timeDiff = today.getTime() - date.getTime();
- var differenceInDays = Math.ceil(timeDiff / toMs("day")) - 1;
- var duration = timeDiff - differenceInDays * hiddenInterval;
- var cellCount = duration / this.getCellDuration();
- return cellCount * cellWidth
- },
- _renderIndicator: function(height, rtlOffset, $container, groupCount) {
- var $indicator;
- var width = this.getIndicationWidth();
- if ("vertical" === this.option("groupOrientation")) {
- $indicator = this._createIndicator($container);
- $indicator.height($container.get(0).getBoundingClientRect().height);
- $indicator.css("left", rtlOffset ? rtlOffset - width : width)
- } else {
- for (var i = 0; i < groupCount; i++) {
- var offset = this._getCellCount() * this.getCellWidth() * i;
- $indicator = this._createIndicator($container);
- $indicator.height($container.get(0).getBoundingClientRect().height);
- $indicator.css("left", rtlOffset ? rtlOffset - width - offset : width + offset)
- }
- }
- },
- _isVerticalShader: function() {
- return false
- },
- _isCurrentTimeHeaderCell: function(headerIndex) {
- var result = false;
- if (this.option("showCurrentTimeIndicator") && this._needRenderDateTimeIndicator()) {
- var date = this._getDateByIndex(headerIndex);
- var now = this._getToday();
- date = new Date(date);
- if (dateUtils.sameDate(now, date)) {
- var startCellDate = new Date(date);
- var endCellDate = new Date(date);
- endCellDate = endCellDate.setMilliseconds(date.getMilliseconds() + this.getCellDuration());
- result = dateUtils.dateInRange(now, startCellDate, endCellDate)
- }
- }
- return result
- },
- _cleanView: function() {
- this.callBase();
- this._$sidebarTable.empty()
- },
- _visibilityChanged: function(visible) {
- this.callBase(visible)
- },
- _setTableSizes: function() {
- var cellHeight = this.getCellHeight();
- var minHeight = this._getWorkSpaceMinHeight();
- var $groupCells = this._$sidebarTable.find("tr");
- var height = cellHeight * $groupCells.length;
- if (height < minHeight) {
- height = minHeight
- }
- this._$sidebarTable.height(height);
- this._$dateTable.height(height);
- this.callBase()
- },
- _getWorkSpaceMinHeight: function() {
- var minHeight = this._getWorkSpaceHeight();
- var workspaceContainerHeight = this.$element().outerHeight(true) - this.getHeaderPanelHeight() - 2 * DATE_TABLE_CELL_BORDER - DATE_TABLE_HEADER_MARGIN;
- if (minHeight < workspaceContainerHeight) {
- minHeight = workspaceContainerHeight
- }
- return minHeight
- },
- _makeGroupRows: function(groups, groupByDate) {
- var tableCreatorStrategy = "vertical" === this.option("groupOrientation") ? tableCreator.VERTICAL : tableCreator.HORIZONTAL;
- return tableCreator.makeGroupedTable(tableCreatorStrategy, groups, {
- groupRowClass: this._getGroupRowClass(),
- groupHeaderRowClass: this._getGroupRowClass(),
- groupHeaderClass: this._getGroupHeaderClass.bind(this),
- groupHeaderContentClass: this._getGroupHeaderContentClass()
- }, this._getCellCount() || 1, this.option("resourceCellTemplate"), this._getTotalRowCount(this._getGroupCount()), groupByDate)
- },
- _ensureGroupHeaderCellsHeight: function(cellHeight) {
- var minCellHeight = this._calculateMinCellHeight();
- if (cellHeight < minCellHeight) {
- return minCellHeight
- }
- return cellHeight
- },
- _calculateMinCellHeight: function() {
- var dateTable = this._getDateTable();
- var dateTableRowSelector = "." + this._getDateTableRowClass();
- return dateTable.get(0).getBoundingClientRect().height / dateTable.find(dateTableRowSelector).length - 2 * DATE_TABLE_CELL_BORDER
- },
- _getCellCoordinatesByIndex: function(index) {
- return {
- cellIndex: index % this._getCellCount(),
- rowIndex: 0
- }
- },
- _getCellByCoordinates: function(cellCoordinates, groupIndex) {
- var indexes = this._groupedStrategy.prepareCellIndexes(cellCoordinates, groupIndex);
- return this._$dateTable.find("tr").eq(indexes.rowIndex).find("td").eq(indexes.cellIndex)
- },
- _getWorkSpaceWidth: function() {
- return this._$dateTable.outerWidth(true)
- },
- _getGroupIndexByCell: function($cell) {
- return $cell.parent().index()
- },
- _getIndicationFirstViewDate: function() {
- return new Date(this._firstViewDate)
- },
- _getIntervalBetween: function(currentDate, allDay) {
- var startDayHour = this.option("startDayHour");
- var endDayHour = this.option("endDayHour");
- var firstViewDate = this.getStartViewDate();
- var firstViewDateTime = firstViewDate.getTime();
- var hiddenInterval = (24 - endDayHour + startDayHour) * toMs("hour");
- var timeZoneOffset = dateUtils.getTimezonesDifference(firstViewDate, currentDate);
- var apptStart = currentDate.getTime();
- var fullInterval = apptStart - firstViewDateTime - timeZoneOffset;
- var fullDays = Math.floor(fullInterval / toMs("day"));
- var tailDuration = fullInterval - fullDays * toMs("day");
- var tailDelta = 0;
- var cellCount = this._getCellCountInDay() * (fullDays - this._getWeekendsCount(fullDays));
- var gapBeforeAppt = apptStart - dateUtils.trimTime(new Date(currentDate)).getTime();
- var result = cellCount * this.option("hoursInterval") * toMs("hour");
- if (!allDay) {
- if (currentDate.getHours() < startDayHour) {
- tailDelta = tailDuration - hiddenInterval + gapBeforeAppt
- } else {
- if (currentDate.getHours() >= startDayHour && currentDate.getHours() < endDayHour) {
- tailDelta = tailDuration
- } else {
- if (currentDate.getHours() >= startDayHour && currentDate.getHours() >= endDayHour) {
- tailDelta = tailDuration - (gapBeforeAppt - endDayHour * toMs("hour"))
- } else {
- if (!fullDays) {
- result = fullInterval
- }
- }
- }
- }
- result += tailDelta
- }
- return result
- },
- _getWeekendsCount: function() {
- return 0
- },
- getAllDayContainer: function() {
- return null
- },
- getTimePanelWidth: function() {
- return 0
- },
- getPositionShift: function(timeShift) {
- var positionShift = this.callBase(timeShift);
- var left = this.getCellWidth() * timeShift;
- if (this.option("rtlEnabled")) {
- left *= -1
- }
- left += positionShift.left;
- return {
- top: 0,
- left: left,
- cellPosition: left
- }
- },
- getVisibleBounds: function() {
- var isRtl = this.option("rtlEnabled");
- var result = {};
- var $scrollable = this.getScrollable().$element();
- var cellWidth = this.getCellWidth();
- var scrollableOffset = isRtl ? this.getScrollableOuterWidth() - this.getScrollableScrollLeft() : this.getScrollableScrollLeft();
- var scrolledCellCount = scrollableOffset / cellWidth;
- var visibleCellCount = $scrollable.width() / cellWidth;
- var totalCellCount = isRtl ? scrolledCellCount - visibleCellCount : scrolledCellCount + visibleCellCount;
- var leftDate = this._getDateByIndex(scrolledCellCount);
- var rightDate = this._getDateByIndex(totalCellCount);
- if (isRtl) {
- leftDate = this._getDateByIndex(totalCellCount);
- rightDate = this._getDateByIndex(scrolledCellCount)
- }
- result.left = {
- hours: leftDate.getHours(),
- minutes: leftDate.getMinutes() >= 30 ? 30 : 0,
- date: dateUtils.trimTime(leftDate)
- };
- result.right = {
- hours: rightDate.getHours(),
- minutes: rightDate.getMinutes() >= 30 ? 30 : 0,
- date: dateUtils.trimTime(rightDate)
- };
- return result
- },
- needUpdateScrollPosition: function(hours, minutes, bounds, date) {
- var isUpdateNeeded = false;
- isUpdateNeeded = this._dateWithinBounds(bounds, date);
- if (hours < bounds.left.hours || hours > bounds.right.hours) {
- isUpdateNeeded = true
- }
- if (hours === bounds.left.hours && minutes < bounds.left.minutes) {
- isUpdateNeeded = true
- }
- if (hours === bounds.right.hours && minutes > bounds.right.minutes) {
- isUpdateNeeded = true
- }
- return isUpdateNeeded
- },
- getIntervalDuration: function(allDay) {
- return this.getCellDuration()
- },
- _dateWithinBounds: function(bounds, date) {
- var trimmedDate = dateUtils.trimTime(new Date(date));
- var isUpdateNeeded = false;
- if (trimmedDate < bounds.left.date || trimmedDate > bounds.right.date) {
- isUpdateNeeded = true
- }
- return isUpdateNeeded
- },
- _supportCompactDropDownAppointments: function() {
- return false
- },
- getCellMinWidth: function() {
- return 0
- },
- getWorkSpaceLeftOffset: function() {
- return 0
- },
- scrollToTime: function(hours, minutes, date) {
- var coordinates = this._getScrollCoordinates(hours, minutes, date);
- var scrollable = this.getScrollable();
- var offset = this.option("rtlEnabled") ? this.getScrollableContainer().get(0).getBoundingClientRect().width : 0;
- if (this.option("templatesRenderAsynchronously")) {
- setTimeout(function() {
- scrollable.scrollBy({
- left: coordinates.left - scrollable.scrollLeft() - offset,
- top: 0
- })
- })
- } else {
- scrollable.scrollBy({
- left: coordinates.left - scrollable.scrollLeft() - offset,
- top: 0
- })
- }
- }
- });
- registerComponent("dxSchedulerTimeline", SchedulerTimeline);
- module.exports = SchedulerTimeline;
|