| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572 |
- /**
- * DevExtreme (ui/scheduler/ui.scheduler.appointment_model.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 _config = require("../../core/config");
- var _config2 = _interopRequireDefault(_config);
- var _iterator = require("../../core/utils/iterator");
- var _iterator2 = _interopRequireDefault(_iterator);
- var _date_serialization = require("../../core/utils/date_serialization");
- var _date_serialization2 = _interopRequireDefault(_date_serialization);
- var _utils = require("./utils.recurrence");
- var _utils2 = _interopRequireDefault(_utils);
- var _date = require("../../core/utils/date");
- var _date2 = _interopRequireDefault(_date);
- var _common = require("../../core/utils/common");
- var _common2 = _interopRequireDefault(_common);
- var _type = require("../../core/utils/type");
- var _type2 = _interopRequireDefault(_type);
- var _array = require("../../core/utils/array");
- var _array2 = _interopRequireDefault(_array);
- var _extend = require("../../core/utils/extend");
- var _query = require("../../data/query");
- var _query2 = _interopRequireDefault(_query);
- function _interopRequireDefault(obj) {
- return obj && obj.__esModule ? obj : {
- "default": obj
- }
- }
- function _classCallCheck(instance, Constructor) {
- if (!(instance instanceof Constructor)) {
- throw new TypeError("Cannot call a class as a function")
- }
- }
- function _defineProperties(target, props) {
- for (var i = 0; i < props.length; i++) {
- var descriptor = props[i];
- descriptor.enumerable = descriptor.enumerable || false;
- descriptor.configurable = true;
- if ("value" in descriptor) {
- descriptor.writable = true
- }
- Object.defineProperty(target, descriptor.key, descriptor)
- }
- }
- function _createClass(Constructor, protoProps, staticProps) {
- if (protoProps) {
- _defineProperties(Constructor.prototype, protoProps)
- }
- if (staticProps) {
- _defineProperties(Constructor, staticProps)
- }
- Object.defineProperty(Constructor, "prototype", {
- writable: false
- });
- return Constructor
- }
- var toMs = _date2.default.dateToMilliseconds;
- var DATE_FILTER_POSITION = 0;
- var USER_FILTER_POSITION = 1;
- var FilterMaker = function() {
- function FilterMaker(dataAccessors) {
- _classCallCheck(this, FilterMaker);
- this._filterRegistry = null;
- this._dataAccessors = dataAccessors
- }
- _createClass(FilterMaker, [{
- key: "isRegistered",
- value: function() {
- return !!this._filterRegistry
- }
- }, {
- key: "clearRegistry",
- value: function() {
- delete this._filterRegistry
- }
- }, {
- key: "make",
- value: function(type, args) {
- if (!this._filterRegistry) {
- this._filterRegistry = {}
- }
- this._make(type).apply(this, args)
- }
- }, {
- key: "_make",
- value: function(type) {
- var _this = this;
- switch (type) {
- case "date":
- return function(min, max, useAccessors) {
- var startDate = useAccessors ? _this._dataAccessors.getter.startDate : _this._dataAccessors.expr.startDateExpr;
- var endDate = useAccessors ? _this._dataAccessors.getter.endDate : _this._dataAccessors.expr.endDateExpr;
- var recurrenceRule = _this._dataAccessors.expr.recurrenceRuleExpr;
- _this._filterRegistry.date = [
- [
- [endDate, ">", min],
- [startDate, "<", max]
- ], "or", [recurrenceRule, "startswith", "freq"], "or", [
- [endDate, min],
- [startDate, min]
- ]
- ];
- if (!recurrenceRule) {
- _this._filterRegistry.date.splice(1, 2)
- }
- };
- case "user":
- return function(userFilter) {
- _this._filterRegistry.user = userFilter
- }
- }
- }
- }, {
- key: "combine",
- value: function() {
- var filter = [];
- this._filterRegistry.date && filter.push(this._filterRegistry.date);
- this._filterRegistry.user && filter.push(this._filterRegistry.user);
- return filter
- }
- }, {
- key: "dateFilter",
- value: function() {
- return this._filterRegistry.date
- }
- }]);
- return FilterMaker
- }();
- var compareDateWithStartDayHour = function(startDate, endDate, startDayHour, allDay, severalDays) {
- var startTime = _date2.default.dateTimeFromDecimal(startDayHour);
- var result = startDate.getHours() >= startTime.hours && startDate.getMinutes() >= startTime.minutes || endDate.getHours() === startTime.hours && endDate.getMinutes() > startTime.minutes || endDate.getHours() > startTime.hours || severalDays || allDay;
- return result
- };
- var compareDateWithEndDayHour = function(startDate, endDate, startDayHour, endDayHour, allDay, severalDays, max, min) {
- var hiddenInterval = (24 - endDayHour + startDayHour) * toMs("hour");
- var apptDuration = endDate.getTime() - startDate.getTime();
- var delta = (hiddenInterval - apptDuration) / toMs("hour");
- var apptStartHour = startDate.getHours();
- var apptStartMinutes = startDate.getMinutes();
- var result;
- var endTime = _date2.default.dateTimeFromDecimal(endDayHour);
- var startTime = _date2.default.dateTimeFromDecimal(startDayHour);
- result = apptStartHour < endTime.hours || apptStartHour === endTime.hours && apptStartMinutes < endTime.minutes || allDay && startDate <= max || severalDays && startDate < max && endDate > min && (apptStartHour < endTime.hours || 60 * endDate.getHours() + endDate.getMinutes() > 60 * startTime.hours);
- if (apptDuration < hiddenInterval) {
- if (apptStartHour > endTime.hours && apptStartMinutes > endTime.minutes && delta <= apptStartHour - endDayHour) {
- result = false
- }
- }
- return result
- };
- var AppointmentModel = function() {
- function AppointmentModel(dataSource, dataAccessors, baseAppointmentDuration) {
- _classCallCheck(this, AppointmentModel);
- this.setDataAccessors(dataAccessors);
- this.setDataSource(dataSource);
- this._updatedAppointmentKeys = [];
- this._filterMaker = new FilterMaker(dataAccessors);
- this._baseAppointmentDuration = baseAppointmentDuration
- }
- _createClass(AppointmentModel, [{
- key: "_createFilter",
- value: function(min, max, remoteFiltering, dateSerializationFormat) {
- this._filterMaker.make("date", [min, max]);
- var userFilterPosition = this._excessFiltering() ? this._dataSource.filter()[USER_FILTER_POSITION] : this._dataSource.filter();
- this._filterMaker.make("user", [userFilterPosition]);
- if (remoteFiltering) {
- this._dataSource.filter(this._combineRemoteFilter(dateSerializationFormat))
- }
- }
- }, {
- key: "_excessFiltering",
- value: function() {
- var dateFilter = this._filterMaker.dateFilter();
- var dataSourceFilter = this._dataSource.filter();
- return dataSourceFilter && (_common2.default.equalByValue(dataSourceFilter, dateFilter) || dataSourceFilter.length && _common2.default.equalByValue(dataSourceFilter[DATE_FILTER_POSITION], dateFilter))
- }
- }, {
- key: "_combineFilter",
- value: function() {
- return this._filterMaker.combine()
- }
- }, {
- key: "_getStoreKey",
- value: function(target) {
- var store = this._dataSource.store();
- return store.keyOf(target)
- }
- }, {
- key: "_filterAppointmentByResources",
- value: function(appointment, resources) {
- var _this2 = this;
- var result = false;
- var checkAppointmentResourceValues = function() {
- var resourceGetter = _this2._dataAccessors.getter.resources[resourceName];
- var resource;
- if (_type2.default.isFunction(resourceGetter)) {
- resource = resourceGetter(appointment)
- }
- var appointmentResourceValues = _array2.default.wrapToArray(resource);
- var resourceData = _iterator2.default.map(resources[i].items, function(item) {
- return item.id
- });
- for (var j = 0, itemDataCount = appointmentResourceValues.length; j < itemDataCount; j++) {
- if ((0, _array.inArray)(appointmentResourceValues[j], resourceData) > -1) {
- return true
- }
- }
- return false
- };
- for (var i = 0, len = resources.length; i < len; i++) {
- var resourceName = resources[i].name;
- result = checkAppointmentResourceValues.call(this);
- if (!result) {
- return false
- }
- }
- return result
- }
- }, {
- key: "_filterAppointmentByRRule",
- value: function(appointment, min, max, startDayHour, endDayHour, firstDayOfWeek) {
- var recurrenceRule = appointment.recurrenceRule;
- var recurrenceException = appointment.recurrenceException;
- var allDay = appointment.allDay;
- var result = true;
- var appointmentStartDate = appointment.startDate;
- var appointmentEndDate = appointment.endDate;
- if (allDay || this._appointmentPartInInterval(appointmentStartDate, appointmentEndDate, startDayHour, endDayHour)) {
- var trimmedDates = this._trimDates(min, max);
- min = trimmedDates.min;
- max = new Date(trimmedDates.max.getTime() - toMs("minute"))
- }
- if (recurrenceRule && !_utils2.default.getRecurrenceRule(recurrenceRule).isValid) {
- result = appointmentEndDate > min && appointmentStartDate <= max
- }
- if (result && _utils2.default.getRecurrenceRule(recurrenceRule).isValid) {
- result = _utils2.default.dateInRecurrenceRange({
- rule: recurrenceRule,
- exception: recurrenceException,
- start: appointmentStartDate,
- end: appointmentEndDate,
- min: min,
- max: max,
- firstDayOfWeek: firstDayOfWeek
- })
- }
- return result
- }
- }, {
- key: "_appointmentPartInInterval",
- value: function(startDate, endDate, startDayHour, endDayHour) {
- var apptStartDayHour = startDate.getHours();
- var apptEndDayHour = endDate.getHours();
- return apptStartDayHour <= startDayHour && apptEndDayHour <= endDayHour && apptEndDayHour >= startDayHour || apptEndDayHour >= endDayHour && apptStartDayHour <= endDayHour && apptStartDayHour >= startDayHour
- }
- }, {
- key: "_createCombinedFilter",
- value: function(filterOptions, timeZoneProcessor) {
- var dataAccessors = this._dataAccessors;
- var startDayHour = filterOptions.startDayHour;
- var endDayHour = filterOptions.endDayHour;
- var min = new Date(filterOptions.min);
- var max = new Date(filterOptions.max);
- var resources = filterOptions.resources;
- var firstDayOfWeek = filterOptions.firstDayOfWeek;
- var getRecurrenceException = filterOptions.recurrenceException;
- var that = this;
- return [
- [function(appointment) {
- var result = true;
- var startDate = new Date(dataAccessors.getter.startDate(appointment));
- var endDate = new Date(dataAccessors.getter.endDate(appointment));
- var appointmentTakesAllDay = that.appointmentTakesAllDay(appointment, startDayHour, endDayHour);
- var appointmentTakesSeveralDays = that.appointmentTakesSeveralDays(appointment);
- var isAllDay = dataAccessors.getter.allDay(appointment);
- var appointmentIsLong = appointmentTakesSeveralDays || appointmentTakesAllDay;
- var useRecurrence = _type2.default.isDefined(dataAccessors.getter.recurrenceRule);
- var recurrenceRule;
- if (useRecurrence) {
- recurrenceRule = dataAccessors.getter.recurrenceRule(appointment)
- }
- if (resources && resources.length) {
- result = that._filterAppointmentByResources(appointment, resources)
- }
- if (appointmentTakesAllDay && false === filterOptions.allDay) {
- result = false
- }
- var startDateTimeZone = dataAccessors.getter.startDateTimeZone(appointment);
- var endDateTimeZone = dataAccessors.getter.endDateTimeZone(appointment);
- var comparableStartDate = timeZoneProcessor(startDate, startDateTimeZone);
- var comparableEndDate = timeZoneProcessor(endDate, endDateTimeZone);
- if (result && useRecurrence) {
- var recurrenceException = getRecurrenceException ? getRecurrenceException(appointment) : dataAccessors.getter.recurrenceException(appointment);
- result = that._filterAppointmentByRRule({
- startDate: comparableStartDate,
- endDate: comparableEndDate,
- recurrenceRule: recurrenceRule,
- recurrenceException: recurrenceException,
- allDay: appointmentTakesAllDay
- }, min, max, startDayHour, endDayHour, firstDayOfWeek)
- }
- if (result && comparableEndDate < min && appointmentIsLong && !isAllDay && (!useRecurrence || useRecurrence && !recurrenceRule)) {
- result = false
- }
- if (result && void 0 !== startDayHour) {
- result = compareDateWithStartDayHour(comparableStartDate, comparableEndDate, startDayHour, appointmentTakesAllDay, appointmentTakesSeveralDays)
- }
- if (result && void 0 !== endDayHour) {
- result = compareDateWithEndDayHour(comparableStartDate, comparableEndDate, startDayHour, endDayHour, appointmentTakesAllDay, appointmentTakesSeveralDays, max, min)
- }
- if (result && useRecurrence && !recurrenceRule) {
- if (comparableEndDate < min && !isAllDay) {
- result = false
- }
- }
- return result
- }]
- ]
- }
- }, {
- key: "setDataSource",
- value: function(dataSource) {
- this._dataSource = dataSource;
- this.cleanModelState();
- this._initStoreChangeHandlers();
- this._filterMaker && this._filterMaker.clearRegistry()
- }
- }, {
- key: "_initStoreChangeHandlers",
- value: function() {
- var _this3 = this;
- this._dataSource && this._dataSource.store().on("updating", function(newItem) {
- _this3._updatedAppointment = newItem
- }.bind(this));
- this._dataSource && this._dataSource.store().on("push", function(items) {
- items.forEach(function(item) {
- _this3._updatedAppointmentKeys.push({
- key: _this3._dataSource.store().key(),
- value: item.key
- })
- }.bind(_this3))
- }.bind(this))
- }
- }, {
- key: "getUpdatedAppointment",
- value: function() {
- return this._updatedAppointment
- }
- }, {
- key: "getUpdatedAppointmentKeys",
- value: function() {
- return this._updatedAppointmentKeys
- }
- }, {
- key: "cleanModelState",
- value: function() {
- this._updatedAppointment = null;
- this._updatedAppointmentKeys = []
- }
- }, {
- key: "setDataAccessors",
- value: function(dataAccessors) {
- this._dataAccessors = dataAccessors;
- this._filterMaker = new FilterMaker(dataAccessors)
- }
- }, {
- key: "filterByDate",
- value: function(min, max, remoteFiltering, dateSerializationFormat) {
- if (!this._dataSource) {
- return
- }
- var trimmedDates = this._trimDates(min, max);
- if (!this._filterMaker.isRegistered()) {
- this._createFilter(trimmedDates.min, trimmedDates.max, remoteFiltering, dateSerializationFormat)
- } else {
- this._filterMaker.make("date", [trimmedDates.min, trimmedDates.max]);
- if (this._dataSource.filter() && this._dataSource.filter().length > 1) {
- var userFilter = this._serializeRemoteFilter([this._dataSource.filter()[1]], dateSerializationFormat);
- this._filterMaker.make("user", userFilter)
- }
- if (remoteFiltering) {
- this._dataSource.filter(this._combineRemoteFilter(dateSerializationFormat))
- }
- }
- }
- }, {
- key: "_combineRemoteFilter",
- value: function(dateSerializationFormat) {
- var combinedFilter = this._filterMaker.combine();
- return this._serializeRemoteFilter(combinedFilter, dateSerializationFormat)
- }
- }, {
- key: "_serializeRemoteFilter",
- value: function(filter, dateSerializationFormat) {
- if (!Array.isArray(filter)) {
- return filter
- }
- filter = (0, _extend.extend)([], filter);
- var startDate = this._dataAccessors.expr.startDateExpr;
- var endDate = this._dataAccessors.expr.endDateExpr;
- if (_type2.default.isString(filter[0])) {
- if ((0, _config2.default)().forceIsoDateParsing && filter.length > 1) {
- if (filter[0] === startDate || filter[0] === endDate) {
- filter[filter.length - 1] = _date_serialization2.default.serializeDate(new Date(filter[filter.length - 1]), dateSerializationFormat)
- }
- }
- }
- for (var i = 0; i < filter.length; i++) {
- filter[i] = this._serializeRemoteFilter(filter[i], dateSerializationFormat)
- }
- return filter
- }
- }, {
- key: "filterLoadedAppointments",
- value: function(filterOptions, timeZoneProcessor) {
- if (!_type2.default.isFunction(timeZoneProcessor)) {
- timeZoneProcessor = function(date) {
- return date
- }
- }
- var combinedFilter = this._createCombinedFilter(filterOptions, timeZoneProcessor);
- if (this._filterMaker.isRegistered()) {
- var trimmedDates = this._trimDates(filterOptions.min, filterOptions.max);
- this._filterMaker.make("date", [trimmedDates.min, trimmedDates.max, true]);
- var dateFilter = this.customizeDateFilter(this._filterMaker.combine(), timeZoneProcessor);
- combinedFilter.push([dateFilter])
- }
- return (0, _query2.default)(this._dataSource.items()).filter(combinedFilter).toArray()
- }
- }, {
- key: "_trimDates",
- value: function(min, max) {
- var minCopy = _date2.default.trimTime(new Date(min));
- var maxCopy = _date2.default.trimTime(new Date(max));
- maxCopy.setDate(maxCopy.getDate() + 1);
- return {
- min: minCopy,
- max: maxCopy
- }
- }
- }, {
- key: "hasAllDayAppointments",
- value: function(items, startDayHour, endDayHour) {
- if (!items) {
- return false
- }
- var that = this;
- var result = false;
- _iterator2.default.each(items, function(index, item) {
- if (that.appointmentTakesAllDay(item, startDayHour, endDayHour)) {
- result = true;
- return false
- }
- });
- return result
- }
- }, {
- key: "appointmentTakesAllDay",
- value: function(appointment, startDayHour, endDayHour) {
- var dataAccessors = this._dataAccessors;
- var startDate = dataAccessors.getter.startDate(appointment);
- var endDate = dataAccessors.getter.endDate(appointment);
- var allDay = dataAccessors.getter.allDay(appointment);
- return allDay || this._appointmentHasAllDayDuration(startDate, endDate, startDayHour, endDayHour)
- }
- }, {
- key: "_appointmentHasAllDayDuration",
- value: function(startDate, endDate, startDayHour, endDayHour) {
- startDate = new Date(startDate);
- endDate = new Date(endDate);
- var dayDuration = 24;
- var appointmentDurationInHours = this._getAppointmentDurationInHours(startDate, endDate);
- return appointmentDurationInHours >= dayDuration || this._appointmentHasShortDayDuration(startDate, endDate, startDayHour, endDayHour)
- }
- }, {
- key: "_appointmentHasShortDayDuration",
- value: function(startDate, endDate, startDayHour, endDayHour) {
- var appointmentDurationInHours = this._getAppointmentDurationInHours(startDate, endDate);
- var shortDayDurationInHours = endDayHour - startDayHour;
- return appointmentDurationInHours >= shortDayDurationInHours && startDate.getHours() === startDayHour && endDate.getHours() === endDayHour
- }
- }, {
- key: "_getAppointmentDurationInHours",
- value: function(startDate, endDate) {
- return (endDate.getTime() - startDate.getTime()) / toMs("hour")
- }
- }, {
- key: "appointmentTakesSeveralDays",
- value: function(appointment) {
- var dataAccessors = this._dataAccessors;
- var startDate = dataAccessors.getter.startDate(appointment);
- var endDate = dataAccessors.getter.endDate(appointment);
- var startDateCopy = _date2.default.trimTime(new Date(startDate));
- var endDateCopy = _date2.default.trimTime(new Date(endDate));
- return startDateCopy.getTime() !== endDateCopy.getTime()
- }
- }, {
- key: "customizeDateFilter",
- value: function(dateFilter, timeZoneProcessor) {
- var _this4 = this;
- var currentFilter = (0, _extend.extend)(true, [], dateFilter);
- return function(appointment) {
- var startDate = new Date(_this4._dataAccessors.getter.startDate(appointment));
- var endDate = new Date(_this4._dataAccessors.getter.endDate(appointment));
- endDate = _this4.fixWrongEndDate(appointment, startDate, endDate);
- appointment = (0, _extend.extend)(true, {}, appointment);
- var startDateTimeZone = _this4._dataAccessors.getter.startDateTimeZone(appointment);
- var endDateTimeZone = _this4._dataAccessors.getter.endDateTimeZone(appointment);
- var comparableStartDate = timeZoneProcessor(startDate, startDateTimeZone);
- var comparableEndDate = timeZoneProcessor(endDate, endDateTimeZone);
- _this4._dataAccessors.setter.startDate(appointment, comparableStartDate);
- _this4._dataAccessors.setter.endDate(appointment, comparableEndDate);
- return (0, _query2.default)([appointment]).filter(currentFilter).toArray().length > 0
- }.bind(this)
- }
- }, {
- key: "fixWrongEndDate",
- value: function(appointment, startDate, endDate) {
- if (this._isEndDateWrong(appointment, startDate, endDate)) {
- if (this._dataAccessors.getter.allDay(appointment)) {
- endDate = _date2.default.setToDayEnd(new Date(startDate))
- } else {
- endDate = new Date(startDate.getTime() + this._baseAppointmentDuration * toMs("minute"))
- }
- this._dataAccessors.setter.endDate(appointment, endDate)
- }
- return endDate
- }
- }, {
- key: "_isEndDateWrong",
- value: function(appointment, startDate, endDate) {
- return !endDate || isNaN(endDate.getTime()) || startDate.getTime() > endDate.getTime()
- }
- }, {
- key: "add",
- value: function(data, tz) {
- var _this5 = this;
- return this._dataSource.store().insert(data).done(function() {
- _this5._dataSource.load()
- }.bind(this))
- }
- }, {
- key: "update",
- value: function(target, data) {
- var _this6 = this;
- var key = this._getStoreKey(target);
- return this._dataSource.store().update(key, data).done(function() {
- _this6._dataSource.load()
- }.bind(this))
- }
- }, {
- key: "remove",
- value: function(target) {
- var _this7 = this;
- var key = this._getStoreKey(target);
- return this._dataSource.store().remove(key).done(function() {
- _this7._dataSource.load()
- }.bind(this))
- }
- }]);
- return AppointmentModel
- }();
- module.exports = AppointmentModel;
|