UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

1,188 lines (1,187 loc) • 79 kB
/** * DevExtreme (esm/ui/scheduler/ui.scheduler.js) * Version: 21.1.4 * Build date: Mon Jun 21 2021 * * Copyright (c) 2012 - 2021 Developer Express Inc. ALL RIGHTS RESERVED * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/ */ import _extends from "@babel/runtime/helpers/esm/extends"; import registerComponent from "../../core/component_registrator"; import config from "../../core/config"; import devices from "../../core/devices"; import $ from "../../core/renderer"; import { BindableTemplate } from "../../core/templates/bindable_template"; import { EmptyTemplate } from "../../core/templates/empty_template"; import { inArray } from "../../core/utils/array"; import browser from "../../core/utils/browser"; import Callbacks from "../../core/utils/callbacks"; import { noop } from "../../core/utils/common"; import { compileGetter, compileSetter } from "../../core/utils/data"; import { getBoundingRect } from "../../core/utils/position"; import dateUtils from "../../core/utils/date"; import dateSerialization from "../../core/utils/date_serialization"; import { Deferred, when, fromPromise } from "../../core/utils/deferred"; import { extend } from "../../core/utils/extend"; import { each } from "../../core/utils/iterator"; import { touch } from "../../core/utils/support"; import { isDefined, isString, isObject, isFunction, isEmptyObject, isDeferred, isPromise } from "../../core/utils/type"; import { hasWindow } from "../../core/utils/window"; import DataHelperMixin from "../../data_helper"; import { triggerResizeEvent } from "../../events/visibility_change"; import dateLocalization from "../../localization/date"; import messageLocalization from "../../localization/message"; import { custom as customDialog } from "../dialog"; import { isMaterial } from "../themes"; import errors from "../widget/ui.errors"; import Widget from "../widget/ui.widget"; import AppointmentPopup from "./appointmentPopup"; import { CompactAppointmentsHelper } from "./compactAppointmentsHelper"; import { DesktopTooltipStrategy } from "./tooltip_strategies/desktopTooltipStrategy"; import { MobileTooltipStrategy } from "./tooltip_strategies/mobileTooltipStrategy"; import { hide as hideLoading, show as showLoading } from "./loading"; import AppointmentCollection from "./appointments/appointmentCollection"; import AppointmentLayoutManager from "./appointments.layout_manager"; import SchedulerAppointmentModel from "./appointment_model"; import { Header } from "./header/header"; import { ResourceManager } from "./resources/resourceManager"; import subscribes from "./subscribes"; import { getRecurrenceProcessor } from "./recurrence"; import timeZoneUtils from "./utils.timeZone"; import SchedulerAgenda from "./workspaces/ui.scheduler.agenda"; import SchedulerTimelineDay from "./workspaces/ui.scheduler.timeline_day"; import SchedulerTimelineMonth from "./workspaces/ui.scheduler.timeline_month"; import SchedulerTimelineWeek from "./workspaces/ui.scheduler.timeline_week"; import SchedulerTimelineWorkWeek from "./workspaces/ui.scheduler.timeline_work_week"; import SchedulerWorkSpaceDay from "./workspaces/ui.scheduler.work_space_day"; import SchedulerWorkSpaceMonth from "./workspaces/ui.scheduler.work_space_month"; import SchedulerWorkSpaceWeek from "./workspaces/ui.scheduler.work_space_week"; import SchedulerWorkSpaceWorkWeek from "./workspaces/ui.scheduler.work_space_work_week"; import AppointmentAdapter from "./appointmentAdapter"; import { TimeZoneCalculator } from "./timeZoneCalculator"; import { AppointmentTooltipInfo } from "./dataStructures"; import { AppointmentSettingsGenerator } from "./appointmentSettingsGenerator"; import AppointmentFilter from "./appointments/appointmentFilter"; import utils from "./utils"; var MINUTES_IN_HOUR = 60; var WIDGET_CLASS = "dx-scheduler"; var WIDGET_SMALL_CLASS = "".concat(WIDGET_CLASS, "-small"); var WIDGET_ADAPTIVE_CLASS = "".concat(WIDGET_CLASS, "-adaptive"); var WIDGET_WIN_NO_TOUCH_CLASS = "".concat(WIDGET_CLASS, "-win-no-touch"); var WIDGET_READONLY_CLASS = "".concat(WIDGET_CLASS, "-readonly"); var WIDGET_SMALL_WIDTH = 400; var FULL_DATE_FORMAT = "yyyyMMddTHHmmss"; var UTC_FULL_DATE_FORMAT = FULL_DATE_FORMAT + "Z"; var VIEWS_CONFIG = { day: { workSpace: SchedulerWorkSpaceDay, renderingStrategy: "vertical" }, week: { workSpace: SchedulerWorkSpaceWeek, renderingStrategy: "vertical" }, workWeek: { workSpace: SchedulerWorkSpaceWorkWeek, renderingStrategy: "vertical" }, month: { workSpace: SchedulerWorkSpaceMonth, renderingStrategy: "horizontalMonth" }, timelineDay: { workSpace: SchedulerTimelineDay, renderingStrategy: "horizontal" }, timelineWeek: { workSpace: SchedulerTimelineWeek, renderingStrategy: "horizontal" }, timelineWorkWeek: { workSpace: SchedulerTimelineWorkWeek, renderingStrategy: "horizontal" }, timelineMonth: { workSpace: SchedulerTimelineMonth, renderingStrategy: "horizontalMonthLine" }, agenda: { workSpace: SchedulerAgenda, renderingStrategy: "agenda" } }; var StoreEventNames = { ADDING: "onAppointmentAdding", ADDED: "onAppointmentAdded", DELETING: "onAppointmentDeleting", DELETED: "onAppointmentDeleted", UPDATING: "onAppointmentUpdating", UPDATED: "onAppointmentUpdated" }; var RECURRENCE_EDITING_MODE = { SERIES: "editSeries", OCCURENCE: "editOccurence", CANCEL: "cancel" }; class Scheduler extends Widget { get appointmentFilter() { return new AppointmentFilter(this) } _getDefaultOptions() { var defaultOptions = extend(super._getDefaultOptions(), { views: ["day", "week"], currentView: "day", currentDate: dateUtils.trimTime(new Date), min: void 0, max: void 0, dateSerializationFormat: void 0, firstDayOfWeek: void 0, groups: [], resources: [], dataSource: null, customizeDateNavigatorText: void 0, appointmentTemplate: "item", dropDownAppointmentTemplate: "dropDownAppointment", appointmentCollectorTemplate: "appointmentCollector", dataCellTemplate: null, timeCellTemplate: null, resourceCellTemplate: null, dateCellTemplate: null, startDayHour: 0, endDayHour: 24, editing: { allowAdding: true, allowDeleting: true, allowDragging: true, allowResizing: true, allowUpdating: true, allowTimeZoneEditing: false, allowEditingTimeZones: false }, showAllDayPanel: true, showCurrentTimeIndicator: true, shadeUntilCurrentTime: false, indicatorUpdateInterval: 3e5, indicatorTime: void 0, recurrenceEditMode: "dialog", cellDuration: 30, maxAppointmentsPerCell: "auto", selectedCellData: [], groupByDate: false, onAppointmentRendered: null, onAppointmentClick: null, onAppointmentDblClick: null, onAppointmentContextMenu: null, onCellClick: null, onCellContextMenu: null, onAppointmentAdding: null, onAppointmentAdded: null, onAppointmentUpdating: null, onAppointmentUpdated: null, onAppointmentDeleting: null, onAppointmentDeleted: null, onAppointmentFormOpening: null, appointmentTooltipTemplate: "appointmentTooltip", appointmentPopupTemplate: "appointmentPopup", crossScrollingEnabled: false, useDropDownViewSwitcher: false, startDateExpr: "startDate", endDateExpr: "endDate", textExpr: "text", descriptionExpr: "description", allDayExpr: "allDay", recurrenceRuleExpr: "recurrenceRule", recurrenceExceptionExpr: "recurrenceException", disabledExpr: "disabled", remoteFiltering: false, timeZone: "", startDateTimeZoneExpr: "startDateTimeZone", endDateTimeZoneExpr: "endDateTimeZone", noDataText: messageLocalization.format("dxCollectionWidget-noDataText"), adaptivityEnabled: false, allowMultipleCellSelection: true, scrolling: { mode: "standard" }, renovateRender: true, _draggingMode: "outlook", _appointmentTooltipOffset: { x: 0, y: 0 }, _appointmentTooltipButtonsPosition: "bottom", _appointmentTooltipOpenButtonText: messageLocalization.format("dxScheduler-openAppointment"), _dropDownButtonIcon: "overflow", _appointmentCountPerCell: 2, _collectorOffset: 0, _appointmentOffset: 26 }); return extend(true, defaultOptions, { integrationOptions: { useDeferUpdateForTemplates: false } }) } _defaultOptionsRules() { return super._defaultOptionsRules().concat([{ device: function() { return "desktop" === devices.real().deviceType && !devices.isSimulator() }, options: { focusStateEnabled: true } }, { device: function() { return !devices.current().generic }, options: { useDropDownViewSwitcher: true, editing: { allowDragging: false, allowResizing: false } } }, { device: function() { return isMaterial() }, options: { useDropDownViewSwitcher: true, dateCellTemplate: function(data, index, element) { var text = data.text; text.split(" ").forEach((function(text, index) { var span = $("<span>").text(text).addClass("dx-scheduler-header-panel-cell-date"); $(element).append(span); if (!index) { $(element).append(" ") } })) }, _appointmentTooltipOffset: { x: 0, y: 11 }, _appointmentTooltipButtonsPosition: "top", _appointmentTooltipOpenButtonText: null, _dropDownButtonIcon: "chevrondown", _appointmentCountPerCell: 1, _collectorOffset: 20, _appointmentOffset: 30 } }]) } _setDeprecatedOptions() { super._setDeprecatedOptions(); extend(this._deprecatedOptions, { dropDownAppointmentTemplate: { since: "19.2", message: "appointmentTooltipTemplate" }, allowEditingTimeZones: { since: "20.1", alias: "allowTimeZoneEditing" } }) } _getAppointmentSettingsGenerator() { return new AppointmentSettingsGenerator(this) } _postponeDataSourceLoading(promise) { this.postponedOperations.add("_reloadDataSource", this._reloadDataSource.bind(this), promise) } _postponeResourceLoading() { var whenLoaded = this.postponedOperations.add("_loadResources", () => this._loadResources()); var resolveCallbacks = new Deferred; whenLoaded.done(resources => { resolveCallbacks.resolve(resources) }); this._postponeDataSourceLoading(whenLoaded); return resolveCallbacks.promise() } _optionChanged(args) { var value = args.value; var name = args.name; switch (args.name) { case "customizeDateNavigatorText": this._updateOption("header", name, value); break; case "firstDayOfWeek": this._updateOption("workSpace", name, value); this._updateOption("header", name, value); break; case "currentDate": value = this._dateOption(name); value = dateUtils.trimTime(new Date(value)); this.option("selectedCellData", []); this._workSpace.option(name, new Date(value)); this._header.option(name, new Date(value)); this._header.option("displayedDate", this._workSpace._getViewStartByOptions()); this._appointments.option("items", []); this._filterAppointmentsByDate(); this._postponeDataSourceLoading(); break; case "dataSource": this._initDataSource(); this._appointmentModel.setDataSource(this._dataSource); this._postponeResourceLoading().done(resources => { this._filterAppointmentsByDate(); this._updateOption("workSpace", "showAllDayPanel", this.option("showAllDayPanel")) }); break; case "min": case "max": value = this._dateOption(name); this._updateOption("header", name, new Date(value)); this._updateOption("workSpace", name, new Date(value)); break; case "views": this._processCurrentView(); if (this._getCurrentViewOptions()) { this.repaint() } else { this._header.option(name, value) } break; case "useDropDownViewSwitcher": this._header.option(name, value); break; case "currentView": this._processCurrentView(); this.fire("validateDayHours"); this.getLayoutManager().initRenderingStrategy(this._getAppointmentsRenderingStrategy()); this._validateCellDuration(); this._appointments.option({ items: [], allowDrag: this._allowDragging(), allowResize: this._allowResizing(), itemTemplate: this._getAppointmentTemplate("appointmentTemplate") }); this._postponeResourceLoading().done(resources => { this._refreshWorkSpace(resources); this._updateHeader(); this._filterAppointmentsByDate(); this._appointments.option("allowAllDayResize", "day" !== value) }); break; case "appointmentTemplate": this._appointments.option("itemTemplate", value); break; case "dateCellTemplate": case "resourceCellTemplate": case "dataCellTemplate": case "timeCellTemplate": this._updateOption("workSpace", name, value); this.repaint(); break; case "groups": this._postponeResourceLoading().done(resources => { this._refreshWorkSpace(resources); this._filterAppointmentsByDate() }); break; case "resources": this._resourcesManager.setResources(this.option("resources")); this._appointmentModel.setDataAccessors(this._combineDataAccessors()); this._postponeResourceLoading().done(resources => { this._appointments.option("items", []); this._refreshWorkSpace(resources); this._filterAppointmentsByDate() }); break; case "startDayHour": case "endDayHour": this.fire("validateDayHours"); this._appointments.option("items", []); this._updateOption("workSpace", name, value); this._appointments.repaint(); this._filterAppointmentsByDate(); this._postponeDataSourceLoading(); break; case StoreEventNames.ADDING: case StoreEventNames.ADDED: case StoreEventNames.UPDATING: case StoreEventNames.UPDATED: case StoreEventNames.DELETING: case StoreEventNames.DELETED: case "onAppointmentFormOpening": this._actions[name] = this._createActionByOption(name); break; case "onAppointmentRendered": this._appointments.option("onItemRendered", this._getAppointmentRenderedAction()); break; case "onAppointmentClick": this._appointments.option("onItemClick", this._createActionByOption(name)); break; case "onAppointmentDblClick": this._appointments.option(name, this._createActionByOption(name)); break; case "onAppointmentContextMenu": this._appointments.option("onItemContextMenu", this._createActionByOption(name)); break; case "noDataText": case "allowMultipleCellSelection": case "selectedCellData": case "accessKey": case "onCellClick": case "onCellContextMenu": this._workSpace.option(name, value); break; case "crossScrollingEnabled": this._postponeResourceLoading().done(resources => { this._appointments.option("items", []); this._refreshWorkSpace(resources); if (this._readyToRenderAppointments) { this._appointments.option("items", this._getAppointmentsToRepaint()) } }); break; case "cellDuration": this._validateCellDuration(); this._appointments.option("items", []); if (this._readyToRenderAppointments) { this._updateOption("workSpace", "hoursInterval", value / 60); this._appointments.option("items", this._getAppointmentsToRepaint()) } break; case "tabIndex": case "focusStateEnabled": this._updateOption("header", name, value); this._updateOption("workSpace", name, value); this._appointments.option(name, value); super._optionChanged(args); break; case "width": this._updateOption("header", name, value); if (this.option("crossScrollingEnabled")) { this._updateOption("workSpace", "width", value) } super._optionChanged(args); this._dimensionChanged(); break; case "height": super._optionChanged(args); this._dimensionChanged(); break; case "editing": this._initEditing(); var editing = this._editing; this._bringEditingModeToAppointments(editing); this.hideAppointmentTooltip(); this._cleanPopup(); break; case "showAllDayPanel": this._postponeResourceLoading().done(resources => { this._filterAppointmentsByDate(); this._updateOption("workSpace", "allDayExpanded", value); this._updateOption("workSpace", name, value) }); break; case "showCurrentTimeIndicator": case "indicatorTime": case "indicatorUpdateInterval": case "shadeUntilCurrentTime": case "groupByDate": this._updateOption("workSpace", name, value); this.repaint(); break; case "appointmentDragging": case "appointmentTooltipTemplate": case "appointmentPopupTemplate": case "recurrenceEditMode": case "remoteFiltering": case "timeZone": case "dropDownAppointmentTemplate": case "appointmentCollectorTemplate": case "_appointmentTooltipOffset": case "_appointmentTooltipButtonsPosition": case "_appointmentTooltipOpenButtonText": case "_dropDownButtonIcon": case "_appointmentCountPerCell": case "_collectorOffset": case "_appointmentOffset": this.repaint(); break; case "dateSerializationFormat": case "maxAppointmentsPerCell": break; case "startDateExpr": case "endDateExpr": case "startDateTimeZoneExpr": case "endDateTimeZoneExpr": case "textExpr": case "descriptionExpr": case "allDayExpr": case "recurrenceRuleExpr": case "recurrenceExceptionExpr": case "disabledExpr": this._updateExpression(name, value); this._appointmentModel.setDataAccessors(this._combineDataAccessors()); this._initAppointmentTemplate(); this.repaint(); break; case "adaptivityEnabled": this._toggleAdaptiveClass(); this.repaint(); break; case "scrolling": this.option("crossScrollingEnabled", this._isHorizontalVirtualScrolling() || this.option("crossScrollingEnabled")); this._updateOption("workSpace", args.fullName, value); break; case "renovateRender": this._updateOption("workSpace", name, value); break; case "_draggingMode": this._workSpace.option("draggingMode", value); break; default: super._optionChanged(args) } } _updateHeader() { var viewCountConfig = this._getViewCountConfig(); this._header.option("intervalCount", viewCountConfig.intervalCount); this._header.option("displayedDate", this._workSpace._getViewStartByOptions()); this._header.option("min", this._dateOption("min")); this._header.option("max", this._dateOption("max")); this._header.option("currentDate", this._dateOption("currentDate")); this._header.option("firstDayOfWeek", this._getCurrentViewOption("firstDayOfWeek")); this._header.option("currentView", this._currentView) } _dateOption(optionName) { var optionValue = this._getCurrentViewOption(optionName); return dateSerialization.deserializeDate(optionValue) } _getSerializationFormat(optionName) { var value = this._getCurrentViewOption(optionName); if ("number" === typeof value) { return "number" } if (!isString(value)) { return } return dateSerialization.getDateSerializationFormat(value) } _bringEditingModeToAppointments(editing) { var editingConfig = { allowDelete: editing.allowUpdating && editing.allowDeleting }; if (!this._isAgenda()) { editingConfig.allowDrag = editing.allowDragging; editingConfig.allowResize = editing.allowResizing; editingConfig.allowAllDayResize = editing.allowResizing && this._supportAllDayResizing() } this._appointments.option(editingConfig); this.repaint() } _isAgenda() { return "agenda" === this._getAppointmentsRenderingStrategy() } _allowDragging() { return this._editing.allowDragging && !this._isAgenda() } _allowResizing() { return this._editing.allowResizing && !this._isAgenda() } _allowAllDayResizing() { return this._editing.allowResizing && this._supportAllDayResizing() } _supportAllDayResizing() { return "day" !== this._getCurrentViewType() || this._currentView.intervalCount > 1 } _isAllDayExpanded(items) { return this.option("showAllDayPanel") && this.appointmentFilter.hasAllDayAppointments(items) } _getTimezoneOffsetByOption(date) { return timeZoneUtils.calculateTimezoneByValue(this.option("timeZone"), date) } _filterAppointmentsByDate() { var dateRange = this._workSpace.getDateRange(); var startDate = this.timeZoneCalculator.createDate(dateRange[0], { path: "fromGrid" }); var endDate = this.timeZoneCalculator.createDate(dateRange[1], { path: "fromGrid" }); this._appointmentModel.filterByDate(startDate, endDate, this.option("remoteFiltering"), this.option("dateSerializationFormat")) } _loadResources() { var groups = this._getCurrentViewOption("groups"); var result = new Deferred; this._resourcesManager.loadResources(groups).done(function(resources) { this._loadedResources = resources; result.resolve(resources) }.bind(this)); return result.promise() } _reloadDataSource() { var result = new Deferred; if (this._dataSource) { this._dataSource.load().done(function() { hideLoading(); this._fireContentReadyAction(result) }.bind(this)).fail((function() { hideLoading(); result.reject() })); this._dataSource.isLoading() && showLoading({ container: this.$element(), position: { of: this.$element() } }) } else { this._fireContentReadyAction(result) } return result.promise() } _fireContentReadyAction(result) { var contentReadyBase = super._fireContentReadyAction.bind(this); var fireContentReady = () => { contentReadyBase(); null === result || void 0 === result ? void 0 : result.resolve() }; if (this._workSpaceRecalculation) { var _this$_workSpaceRecal; null === (_this$_workSpaceRecal = this._workSpaceRecalculation) || void 0 === _this$_workSpaceRecal ? void 0 : _this$_workSpaceRecal.done(() => { fireContentReady() }) } else { fireContentReady() } } _dimensionChanged() { var filteredItems = this.getFilteredItems(); this._toggleSmallClass(); if (!this._isAgenda() && filteredItems && this._isVisible()) { this._workSpace._cleanAllowedPositions(); this._workSpace.option("allDayExpanded", this._isAllDayExpanded(filteredItems)); this._workSpace._dimensionChanged(); var appointments = this._layoutManager.createAppointmentsMap(filteredItems); this._appointments.option("items", appointments) } this.hideAppointmentTooltip(); this._appointmentPopup.triggerResize(); this._appointmentPopup.updatePopupFullScreenMode() } _clean() { this._cleanPopup(); super._clean() } _toggleSmallClass() { var width = getBoundingRect(this.$element().get(0)).width; this.$element().toggleClass(WIDGET_SMALL_CLASS, width < WIDGET_SMALL_WIDTH) } _toggleAdaptiveClass() { this.$element().toggleClass(WIDGET_ADAPTIVE_CLASS, this.option("adaptivityEnabled")) } _visibilityChanged(visible) { visible && this._dimensionChanged() } _dataSourceOptions() { return { paginate: false } } _init() { this._initExpressions({ startDate: this.option("startDateExpr"), endDate: this.option("endDateExpr"), startDateTimeZone: this.option("startDateTimeZoneExpr"), endDateTimeZone: this.option("endDateTimeZoneExpr"), allDay: this.option("allDayExpr"), text: this.option("textExpr"), description: this.option("descriptionExpr"), recurrenceRule: this.option("recurrenceRuleExpr"), recurrenceException: this.option("recurrenceExceptionExpr"), disabled: this.option("disabledExpr") }); super._init(); this._initDataSource(); this._loadedResources = []; this.$element().addClass(WIDGET_CLASS).toggleClass(WIDGET_WIN_NO_TOUCH_CLASS, !!(browser.msie && touch)); this._initEditing(); this._resourcesManager = new ResourceManager(this.option("resources")); var combinedDataAccessors = this._combineDataAccessors(); this._appointmentModel = new SchedulerAppointmentModel(this._dataSource, combinedDataAccessors, this.getAppointmentDurationInMinutes()); this._initActions(); this._compactAppointmentsHelper = new CompactAppointmentsHelper(this); this._asyncTemplatesTimers = []; this._dataSourceLoadedCallback = Callbacks(); this._subscribes = subscribes; this.timeZoneCalculator = new TimeZoneCalculator({ getClientOffset: date => timeZoneUtils.getClientTimezoneOffset(date), getCommonOffset: (date, timeZone) => timeZoneUtils.calculateTimezoneByValue(timeZone || this.option("timeZone"), date), getAppointmentOffset: (date, appointmentTimezone) => timeZoneUtils.calculateTimezoneByValue(appointmentTimezone, date) }) } _initTemplates() { this._initAppointmentTemplate(); this._templateManager.addDefaultTemplates({ appointmentTooltip: new EmptyTemplate, dropDownAppointment: new EmptyTemplate }); super._initTemplates() } _initAppointmentTemplate() { var { expr: expr } = this._dataAccessors; var createGetter = property => compileGetter("appointmentData.".concat(property)); var getDate = getter => data => { var value = getter(data); if (value instanceof Date) { return value.valueOf() } return value }; this._templateManager.addDefaultTemplates({ item: new BindableTemplate(($container, data, model) => this.getAppointmentsInstance()._renderAppointmentTemplate($container, data, model), ["html", "text", "startDate", "endDate", "allDay", "description", "recurrenceRule", "recurrenceException", "startDateTimeZone", "endDateTimeZone"], this.option("integrationOptions.watchMethod"), { text: createGetter(expr.textExpr), startDate: getDate(createGetter(expr.startDateExpr)), endDate: getDate(createGetter(expr.endDateExpr)), startDateTimeZone: createGetter(expr.startDateTimeZoneExpr), endDateTimeZone: createGetter(expr.endDateTimeZoneExpr), allDay: createGetter(expr.allDayExpr), recurrenceRule: createGetter(expr.recurrenceRuleExpr) }) }) } _combineDataAccessors() { var resourcesDataAccessors = this._resourcesManager._dataAccessors; var result = extend(true, {}, this._dataAccessors); each(resourcesDataAccessors, function(type, accessor) { result[type].resources = accessor }.bind(this)); return result } _renderContent() { this._renderContentImpl() } _dataSourceChangedHandler(result) { if (this._readyToRenderAppointments) { this._workSpaceRecalculation.done(function() { this._renderAppointments(); var filteredItems = this.getFilteredItems(); this.getWorkSpace().onDataSourceChanged(filteredItems) }.bind(this)) } } isVirtualScrolling() { var _this$getWorkSpace; return null === (_this$getWorkSpace = this.getWorkSpace()) || void 0 === _this$getWorkSpace ? void 0 : _this$getWorkSpace.isVirtualScrolling() } _filterAppointments() { return this.appointmentFilter.filter() } _renderAppointments() { var workspace = this.getWorkSpace(); this._filteredItems = this._filterAppointments(); workspace.preRenderAppointments({ allDayExpanded: this._isAllDayExpanded(this._filteredItems), appointments: this._filteredItems }); if (this._filteredItems.length && this._isVisible()) { this._appointments.option("items", this._getAppointmentsToRepaint()); this._appointmentModel.cleanModelState() } else { this._appointments.option("items", []) } } _getAppointmentsToRepaint() { var appointments = this._layoutManager.createAppointmentsMap(this._filteredItems); return this._layoutManager.getRepaintedAppointments(appointments, this.getAppointmentsInstance().option("items")) } _initExpressions(fields) { if (!this._dataAccessors) { this._dataAccessors = { getter: {}, setter: {}, expr: {} } } each(fields, function(name, expr) { if (expr) { var getter = compileGetter(expr); var setter = compileSetter(expr); var dateGetter; var dateSetter; if (field = name, "startDate" === field || "endDate" === field) { var that = this; dateGetter = function() { var value = getter.apply(this, arguments); if (config().forceIsoDateParsing) { if (!that.option("dateSerializationFormat")) { var format = dateSerialization.getDateSerializationFormat(value); if (format) { that.option("dateSerializationFormat", format) } } value = dateSerialization.deserializeDate(value) } return value }; dateSetter = function(object, value) { if (config().forceIsoDateParsing || that.option("dateSerializationFormat")) { value = dateSerialization.serializeDate(value, that.option("dateSerializationFormat")) } setter.call(this, object, value) } } this._dataAccessors.getter[name] = dateGetter || getter; this._dataAccessors.setter[name] = dateSetter || setter; this._dataAccessors.expr[name + "Expr"] = expr } else { delete this._dataAccessors.getter[name]; delete this._dataAccessors.setter[name]; delete this._dataAccessors.expr[name + "Expr"] } var field }.bind(this)) } _updateExpression(name, value) { var exprObj = {}; exprObj[name.replace("Expr", "")] = value; this._initExpressions(exprObj) } _initEditing() { var editing = this.option("editing"); this._editing = { allowAdding: !!editing, allowUpdating: !!editing, allowDeleting: !!editing, allowResizing: !!editing, allowDragging: !!editing }; if (isObject(editing)) { this._editing = extend(this._editing, editing) } this._editing.allowDragging = this._editing.allowDragging && this._editing.allowUpdating; this._editing.allowResizing = this._editing.allowResizing && this._editing.allowUpdating; this.$element().toggleClass(WIDGET_READONLY_CLASS, this._isReadOnly()) } _isReadOnly() { var result = true; var editing = this._editing; for (var prop in editing) { if (Object.prototype.hasOwnProperty.call(editing, prop)) { result = result && !editing[prop] } } return result } _dispose() { var _this$_recurrenceDial; this._appointmentTooltip && this._appointmentTooltip.dispose(); null === (_this$_recurrenceDial = this._recurrenceDialog) || void 0 === _this$_recurrenceDial ? void 0 : _this$_recurrenceDial.hide(RECURRENCE_EDITING_MODE.CANCEL); this.hideAppointmentPopup(); this.hideAppointmentTooltip(); this._asyncTemplatesTimers.forEach(clearTimeout); this._asyncTemplatesTimers = []; super._dispose() } _initActions() { this._actions = { onAppointmentAdding: this._createActionByOption(StoreEventNames.ADDING), onAppointmentAdded: this._createActionByOption(StoreEventNames.ADDED), onAppointmentUpdating: this._createActionByOption(StoreEventNames.UPDATING), onAppointmentUpdated: this._createActionByOption(StoreEventNames.UPDATED), onAppointmentDeleting: this._createActionByOption(StoreEventNames.DELETING), onAppointmentDeleted: this._createActionByOption(StoreEventNames.DELETED), onAppointmentFormOpening: this._createActionByOption("onAppointmentFormOpening") } } _getAppointmentRenderedAction() { return this._createActionByOption("onAppointmentRendered", { excludeValidators: ["disabled", "readOnly"] }) } _renderFocusTarget() { return noop() } _initMarkup() { super._initMarkup(); this.fire("validateDayHours"); this._validateCellDuration(); this._processCurrentView(); this._renderHeader(); this._layoutManager = new AppointmentLayoutManager(this, this._getAppointmentsRenderingStrategy()); this._appointments = this._createComponent("<div>", AppointmentCollection, this._appointmentsConfig()); this._appointments.option("itemTemplate", this._getAppointmentTemplate("appointmentTemplate")); this._appointmentTooltip = new(this.option("adaptivityEnabled") ? MobileTooltipStrategy : DesktopTooltipStrategy)(this._getAppointmentTooltipOptions()); this._appointmentPopup = new AppointmentPopup(this); if (this._isLoaded() || this._isDataSourceLoading()) { this._initMarkupCore(this._loadedResources); this._dataSourceChangedHandler(this._dataSource.items()); this._fireContentReadyAction() } else { this._loadResources().done(function(resources) { this._initMarkupCore(resources); this._reloadDataSource() }.bind(this)) } } _getAppointmentTooltipOptions() { return { createComponent: this._createComponent.bind(this), container: this.$element(), getScrollableContainer: this.getWorkSpaceScrollableContainer.bind(this), addDefaultTemplates: this._templateManager.addDefaultTemplates.bind(this._templateManager), getAppointmentTemplate: this._getAppointmentTemplate.bind(this), showAppointmentPopup: this.showAppointmentPopup.bind(this), checkAndDeleteAppointment: this.checkAndDeleteAppointment.bind(this), isAppointmentInAllDayPanel: this.isAppointmentInAllDayPanel.bind(this), createFormattedDateText: (appointment, targetedAppointment, format) => this.fire("getTextAndFormatDate", appointment, targetedAppointment, format), getAppointmentDisabled: appointment => this.createAppointmentAdapter(appointment).disabled } } checkAndDeleteAppointment(appointment, targetedAppointment) { var targetedAdapter = this.createAppointmentAdapter(targetedAppointment); this._checkRecurringAppointment(appointment, targetedAppointment, targetedAdapter.startDate, () => { this.deleteAppointment(appointment) }, true) } _getExtraAppointmentTooltipOptions() { return { rtlEnabled: this.option("rtlEnabled"), focusStateEnabled: this.option("focusStateEnabled"), editing: this.option("editing"), offset: this.option("_appointmentTooltipOffset") } } isAppointmentInAllDayPanel(appointmentData) { var workSpace = this._workSpace; var itTakesAllDay = this.appointmentTakesAllDay(appointmentData); return itTakesAllDay && workSpace.supportAllDayRow() && workSpace.option("showAllDayPanel") } _initMarkupCore(resources) { this._readyToRenderAppointments = hasWindow(); this._workSpace && this._cleanWorkspace(); this._renderWorkSpace(resources); this._appointments.option({ fixedContainer: this._workSpace.getFixedContainer(), allDayContainer: this._workSpace.getAllDayContainer() }); this._waitAsyncTemplate(() => { var _this$_workSpaceRecal2; return null === (_this$_workSpaceRecal2 = this._workSpaceRecalculation) || void 0 === _this$_workSpaceRecal2 ? void 0 : _this$_workSpaceRecal2.resolve() }); this._filterAppointmentsByDate() } _isLoaded() { return this._isResourcesLoaded() && this._isDataSourceLoaded() } _isResourcesLoaded() { return isDefined(this._loadedResources) } _isDataSourceLoaded() { return this._dataSource && this._dataSource.isLoaded() } _render() { this._toggleSmallClass(); this._toggleAdaptiveClass(); super._render() } _renderHeader() { var $header = $("<div>").appendTo(this.$element()); this._header = this._createComponent($header, Header, this._headerConfig()) } _headerConfig() { var currentViewOptions = this._getCurrentViewOptions(); var countConfig = this._getViewCountConfig(); var result = extend({ isAdaptive: this.option("adaptivityEnabled"), firstDayOfWeek: this.option("firstDayOfWeek"), currentView: this._currentView, tabIndex: this.option("tabIndex"), focusStateEnabled: this.option("focusStateEnabled"), width: this.option("width"), rtlEnabled: this.option("rtlEnabled"), useDropDownViewSwitcher: this.option("useDropDownViewSwitcher"), _dropDownButtonIcon: this.option("_dropDownButtonIcon"), customizeDateNavigatorText: this.option("customizeDateNavigatorText") }, currentViewOptions); result.observer = this; result.intervalCount = countConfig.intervalCount; result.views = this.option("views"); result.min = new Date(this._dateOption("min")); result.max = new Date(this._dateOption("max")); result.currentDate = dateUtils.trimTime(new Date(this._dateOption("currentDate"))); result.todayDate = () => { var result = this.timeZoneCalculator.createDate(new Date, { path: "toGrid" }); return result }; return result } _appointmentsConfig() { var that = this; var config = { observer: this, onItemRendered: this._getAppointmentRenderedAction(), onItemClick: this._createActionByOption("onAppointmentClick"), onItemContextMenu: this._createActionByOption("onAppointmentContextMenu"), onAppointmentDblClick: this._createActionByOption("onAppointmentDblClick"), tabIndex: this.option("tabIndex"), focusStateEnabled: this.option("focusStateEnabled"), allowDrag: this._allowDragging(), allowDelete: this._editing.allowUpdating && this._editing.allowDeleting, allowResize: this._allowResizing(), allowAllDayResize: this._allowAllDayResizing(), rtlEnabled: this.option("rtlEnabled"), currentView: this.option("currentView"), onContentReady: function() { that._workSpace && that._workSpace.option("allDayExpanded", that._isAllDayExpanded(that.getFilteredItems())) } }; return config } getCollectorOffset() { if (this._workSpace.needApplyCollectorOffset() && !this.option("adaptivityEnabled")) { return this.option("_collectorOffset") } else { return 0 } } getAppointmentDurationInMinutes() { return this._getCurrentViewOption("cellDuration") } _processCurrentView() { var views = this.option("views"); var currentView = this.option("currentView"); var that = this; this._currentView = null; each(views, (function(_, view) { var isViewIsObject = isObject(view); var viewName = isViewIsObject ? view.name : view; var viewType = view.type; if (currentView === viewName || currentView === viewType) { that._currentView = view; return false } })); if (!this._currentView) { var isCurrentViewValid = !!VIEWS_CONFIG[currentView]; if (isCurrentViewValid) { this._currentView = currentView } else { this._currentView = views[0] } } } _validateCellDuration() { var endDayHour = this._getCurrentViewOption("endDayHour"); var startDayHour = this._getCurrentViewOption("startDayHour"); var cellDuration = this._getCurrentViewOption("cellDuration"); if ((endDayHour - startDayHour) * MINUTES_IN_HOUR % cellDuration !== 0) { errors.log("W1015") } } _getCurrentViewType() { return this._currentView.type || this._currentView } _getAppointmentsRenderingStrategy() { return VIEWS_CONFIG[this._getCurrentViewType()].renderingStrategy } _renderWorkSpace(groups) { this._readyToRenderAppointments && this._toggleSmallClass(); var $workSpace = $("<div>").appendTo(this.$element()); var countConfig = this._getViewCountConfig(); var workSpaceComponent = VIEWS_CONFIG[this._getCurrentViewType()].workSpace; var workSpaceConfig = this._workSpaceConfig(groups, countConfig); this._workSpace = this._createComponent($workSpace, workSpaceComponent, workSpaceConfig); this._allowDragging() && this._workSpace.initDragBehavior(this, this._all); this._workSpace._attachTablesEvents(); this._workSpace.getWorkArea().append(this._appointments.$element()); this._recalculateWorkspace(); countConfig.startDate && this._header && this._header.option("currentDate", this._workSpace._getHeaderDate()); this._appointments.option("_collectorOffset", this.getCollectorOffset()) } _getViewCountConfig() { var currentView = this.option("currentView"); var view = this._getViewByName(currentView); var viewCount = view && view.intervalCount || 1; var startDate = view && view.startDate || null; return { intervalCount: viewCount, startDate: startDate } } _getViewByName(name) { var views = this.option("views"); for (var i = 0; i < views.length; i++) { if (views[i].name === name || views[i].type === name || views[i] === name) { return views[i] } } } _recalculateWorkspace() { this._workSpaceRecalculation = new Deferred; this._waitAsyncTemplate(() => { triggerResizeEvent(this._workSpace.$element()); this._workSpace._refreshDateTimeIndication() }) } _workSpaceConfig(groups, countConfig) { var _currentViewOptions$s; var currentViewOptions = this._getCurrentViewOptions();