ui.scheduler.subscribes.js 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697
  1. /**
  2. * DevExtreme (ui/scheduler/ui.scheduler.subscribes.js)
  3. * Version: 19.1.16
  4. * Build date: Tue Oct 18 2022
  5. *
  6. * Copyright (c) 2012 - 2022 Developer Express Inc. ALL RIGHTS RESERVED
  7. * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
  8. */
  9. "use strict";
  10. var _renderer = require("../../core/renderer");
  11. var _renderer2 = _interopRequireDefault(_renderer);
  12. var _array = require("../../core/utils/array");
  13. var _array2 = _interopRequireDefault(_array);
  14. var _utils = require("./utils.recurrence");
  15. var _utils2 = _interopRequireDefault(_utils);
  16. var _type = require("../../core/utils/type");
  17. var _type2 = _interopRequireDefault(_type);
  18. var _date = require("../../core/utils/date");
  19. var _date2 = _interopRequireDefault(_date);
  20. var _iterator = require("../../core/utils/iterator");
  21. var _translator = require("../../animation/translator");
  22. var _translator2 = _interopRequireDefault(_translator);
  23. var _common = require("../../core/utils/common");
  24. var _extend = require("../../core/utils/extend");
  25. var _date3 = require("../../localization/date");
  26. var _date4 = _interopRequireDefault(_date3);
  27. var _uiScheduler = require("./timezones/ui.scheduler.timezones");
  28. var _uiScheduler2 = _interopRequireDefault(_uiScheduler);
  29. var _deferred = require("../../core/utils/deferred");
  30. function _interopRequireDefault(obj) {
  31. return obj && obj.__esModule ? obj : {
  32. "default": obj
  33. }
  34. }
  35. var MINUTES_IN_HOUR = 60;
  36. var toMs = _date2.default.dateToMilliseconds;
  37. var subscribes = {
  38. isCurrentViewAgenda: function() {
  39. return "agenda" === this.option("currentView")
  40. },
  41. currentViewUpdated: function(currentView) {
  42. this.option("currentView", currentView)
  43. },
  44. currentDateUpdated: function(date) {
  45. this.option("currentDate", date)
  46. },
  47. setCellDataCacheAlias: function(appointment, geometry) {
  48. this._workSpace.setCellDataCacheAlias(appointment, geometry)
  49. },
  50. needCoordinates: function(options) {
  51. var _this = this;
  52. var appointmentData = options.appointmentData;
  53. var startDate = options.startDate;
  54. var endDate = this._getEndDate(appointmentData);
  55. var recurrenceRule = this.fire("getField", "recurrenceRule", appointmentData);
  56. var recurrenceException = this._getRecurrenceException(appointmentData);
  57. var dateRange = this._workSpace.getDateRange();
  58. var allDay = this.appointmentTakesAllDay(appointmentData);
  59. var startViewDate = this.appointmentTakesAllDay(appointmentData) ? _date2.default.trimTime(new Date(dateRange[0])) : dateRange[0];
  60. var originalStartDate = options.originalStartDate || startDate;
  61. var renderingStrategy = this.getLayoutManager().getRenderingStrategyInstance();
  62. var firstDayOfWeek = this.getFirstDayOfWeek();
  63. var recurrenceOptions = {
  64. rule: recurrenceRule,
  65. exception: recurrenceException,
  66. start: originalStartDate,
  67. end: endDate,
  68. min: startViewDate,
  69. max: dateRange[1],
  70. firstDayOfWeek: firstDayOfWeek
  71. };
  72. var dates = _utils2.default.getDatesByRecurrence(recurrenceOptions);
  73. var initialDates;
  74. if (!dates.length) {
  75. dates.push(startDate);
  76. initialDates = dates
  77. } else {
  78. initialDates = dates;
  79. dates = dates.map(function(date) {
  80. return _date2.default.roundDateByStartDayHour(date, _this._getCurrentViewOption("startDayHour"))
  81. })
  82. }
  83. if (renderingStrategy.needSeparateAppointment(allDay)) {
  84. var datesLength = dates.length;
  85. var longParts = [];
  86. var resultDates = [];
  87. var _loop = function(i) {
  88. var endDateOfPart = renderingStrategy.endDate(appointmentData, {
  89. startDate: dates[i]
  90. }, !!recurrenceRule);
  91. longParts = _date2.default.getDatesOfInterval(dates[i], endDateOfPart, {
  92. milliseconds: _this.getWorkSpace().getIntervalDuration(allDay)
  93. });
  94. var maxDate = new Date(dateRange[1]);
  95. resultDates = resultDates.concat(longParts.filter(function(el) {
  96. return new Date(el) < maxDate
  97. }))
  98. };
  99. for (var i = 0; i < datesLength; i++) {
  100. _loop(i)
  101. }
  102. dates = resultDates
  103. }
  104. var itemResources = this._resourcesManager.getResourcesFromItem(appointmentData);
  105. allDay = this.appointmentTakesAllDay(appointmentData) && this._workSpace.supportAllDayRow();
  106. options.callback(this._getCoordinates(initialDates, dates, itemResources, allDay))
  107. },
  108. isGroupedByDate: function() {
  109. return this.getWorkSpace().isGroupedByDate()
  110. },
  111. showAppointmentTooltip: function(options) {
  112. options.skipDateCalculation = true;
  113. options.$appointment = (0, _renderer2.default)(options.target);
  114. var appointmentData = options.data;
  115. var singleAppointmentData = this._getSingleAppointmentData(appointmentData, options);
  116. this.showAppointmentTooltip(appointmentData, options.target, singleAppointmentData)
  117. },
  118. hideAppointmentTooltip: function() {
  119. this.hideAppointmentTooltip()
  120. },
  121. showAddAppointmentPopup: function(appointmentData) {
  122. var processedData = {};
  123. (0, _iterator.each)(["startDate", "endDate", "allDay"], function(_, field) {
  124. if (void 0 !== appointmentData[field]) {
  125. this.fire("setField", field, processedData, appointmentData[field]);
  126. delete appointmentData[field]
  127. }
  128. }.bind(this));
  129. this.showAppointmentPopup((0, _extend.extend)(processedData, appointmentData), true)
  130. },
  131. showEditAppointmentPopup: function(options) {
  132. var appointmentData = options.data;
  133. options.$appointment = (0, _renderer2.default)(options.target);
  134. options.skipHoursProcessing = true;
  135. var singleAppointmentData = this._getSingleAppointmentData(appointmentData, options);
  136. var startDate = this.fire("getField", "startDate", singleAppointmentData);
  137. this.showAppointmentPopup(appointmentData, false, singleAppointmentData, startDate)
  138. },
  139. updateAppointmentAfterResize: function(options) {
  140. var targetAppointment = options.target;
  141. var singleAppointment = this._getSingleAppointmentData(targetAppointment, options);
  142. var startDate = this.fire("getField", "startDate", singleAppointment);
  143. var updatedData = (0, _extend.extend)(true, {}, options.data);
  144. this._convertDatesByTimezoneBack(true, updatedData);
  145. this._checkRecurringAppointment(targetAppointment, singleAppointment, startDate, function() {
  146. this._updateAppointment(targetAppointment, updatedData, function() {
  147. this._appointments.moveAppointmentBack()
  148. })
  149. }.bind(this))
  150. },
  151. updateAppointmentAfterDrag: function(options) {
  152. var target = options.data;
  153. var updatedData = this._getUpdatedData(options);
  154. var newCellIndex = this._workSpace.getDroppableCellIndex();
  155. var oldCellIndex = this._workSpace.getCellIndexByCoordinates(options.coordinates);
  156. var becomeAllDay = this.fire("getField", "allDay", updatedData);
  157. var wasAllDay = this.fire("getField", "allDay", target);
  158. var appointment = (0, _extend.extend)({}, target, updatedData);
  159. var movedToAllDay = this._workSpace.supportAllDayRow() && becomeAllDay;
  160. var cellData = this._workSpace.getCellDataByCoordinates(options.coordinates, movedToAllDay);
  161. var movedBetweenAllDayAndSimple = this._workSpace.supportAllDayRow() && (wasAllDay && !becomeAllDay || !wasAllDay && becomeAllDay);
  162. if (newCellIndex !== oldCellIndex || movedBetweenAllDayAndSimple) {
  163. this._checkRecurringAppointment(target, appointment, cellData.startDate, function() {
  164. this._convertDatesByTimezoneBack(true, updatedData, appointment);
  165. this._updateAppointment(target, appointment, function() {
  166. this._appointments.moveAppointmentBack()
  167. })
  168. }.bind(this))
  169. } else {
  170. this._appointments.moveAppointmentBack()
  171. }
  172. },
  173. deleteAppointment: function(options) {
  174. options.$appointment = (0, _renderer2.default)(options.target);
  175. var appointmentData = options.data;
  176. var singleAppointmentData = this._getSingleAppointmentData(appointmentData, options);
  177. var startDate = this.fire("getField", "startDate", singleAppointmentData);
  178. this._checkRecurringAppointment(appointmentData, singleAppointmentData, startDate, function() {
  179. this.deleteAppointment(appointmentData)
  180. }.bind(this), true)
  181. },
  182. getResourceForPainting: function() {
  183. return this._resourcesManager.getResourceForPainting(this._getCurrentViewOption("groups"))
  184. },
  185. getAppointmentColor: function(options) {
  186. var resourcesManager = this._resourcesManager;
  187. var resourceForPainting = resourcesManager.getResourceForPainting(this._getCurrentViewOption("groups"));
  188. var response = (new _deferred.Deferred).resolve().promise();
  189. if (resourceForPainting) {
  190. var field = resourcesManager.getField(resourceForPainting);
  191. var groupIndex = options.groupIndex;
  192. var groups = this._workSpace._getCellGroups(groupIndex);
  193. var resourceValues = _array2.default.wrapToArray(resourcesManager.getDataAccessors(field, "getter")(options.itemData));
  194. var groupId = resourceValues.length ? resourceValues[0] : void 0;
  195. for (var i = 0; i < groups.length; i++) {
  196. if (groups[i].name === field) {
  197. groupId = groups[i].id;
  198. break
  199. }
  200. }
  201. response = resourcesManager.getResourceColor(field, groupId)
  202. }
  203. options.callback(response)
  204. },
  205. getHeaderHeight: function() {
  206. return this._header._$element && parseInt(this._header._$element.outerHeight(), 10)
  207. },
  208. getResourcesFromItem: function(options) {
  209. options.callback(this._resourcesManager.getResourcesFromItem(options.itemData))
  210. },
  211. getBoundOffset: function(options) {
  212. options.callback({
  213. top: -this.getWorkSpaceAllDayHeight()
  214. })
  215. },
  216. appointmentTakesAllDay: function(options) {
  217. options.callback(this.appointmentTakesAllDay(options.appointment))
  218. },
  219. appointmentTakesSeveralDays: function(appointment) {
  220. return this._appointmentModel.appointmentTakesSeveralDays(appointment)
  221. },
  222. appointmentFocused: function() {
  223. this._workSpace.restoreScrollTop()
  224. },
  225. getResizableAppointmentArea: function(options) {
  226. var area;
  227. var allDay = options.allDay;
  228. var groups = this._getCurrentViewOption("groups");
  229. var isGrouped = groups && groups.length;
  230. if (isGrouped) {
  231. if (allDay || this.getLayoutManager().getRenderingStrategyInstance()._needHorizontalGroupBounds()) {
  232. var horizontalGroupBounds = this._workSpace.getGroupBounds(options.coordinates);
  233. area = {
  234. left: horizontalGroupBounds.left,
  235. right: horizontalGroupBounds.right,
  236. top: 0,
  237. bottom: 0
  238. }
  239. }
  240. if (this.getLayoutManager().getRenderingStrategyInstance()._needVerticalGroupBounds(allDay) && this._workSpace._isVerticalGroupedWorkSpace()) {
  241. var verticalGroupBounds = this._workSpace.getGroupBounds(options.coordinates);
  242. area = {
  243. left: 0,
  244. right: 0,
  245. top: verticalGroupBounds.top,
  246. bottom: verticalGroupBounds.bottom
  247. }
  248. }
  249. }
  250. options.callback(area)
  251. },
  252. needRecalculateResizableArea: function() {
  253. return this.getWorkSpace().needRecalculateResizableArea()
  254. },
  255. getDraggableAppointmentArea: function(options) {
  256. options.callback(this.getWorkSpaceScrollableContainer())
  257. },
  258. getAppointmentGeometry: function(settings) {
  259. return this.getLayoutManager().getRenderingStrategyInstance().getAppointmentGeometry(settings)
  260. },
  261. isAllDay: function(appointmentData) {
  262. return this.getLayoutManager().getRenderingStrategyInstance().isAllDay(appointmentData)
  263. },
  264. getDeltaTime: function(e, initialSize, itemData) {
  265. return this.getLayoutManager().getRenderingStrategyInstance().getDeltaTime(e, initialSize, itemData)
  266. },
  267. getDropDownAppointmentWidth: function(isAllDay) {
  268. return this.getLayoutManager().getRenderingStrategyInstance().getDropDownAppointmentWidth(this._getViewCountConfig().intervalCount, isAllDay)
  269. },
  270. getDropDownAppointmentHeight: function() {
  271. return this.getLayoutManager().getRenderingStrategyInstance().getDropDownAppointmentHeight()
  272. },
  273. getStartDate: function(appointmentData, skipNormalize) {
  274. return this._getStartDate(appointmentData, skipNormalize)
  275. },
  276. getCellWidth: function() {
  277. return this._cellWidth
  278. },
  279. getCellHeight: function() {
  280. return this._cellHeight
  281. },
  282. getResizableStep: function() {
  283. var cellWidth = this._cellWidth;
  284. var workSpace = this.getWorkSpace();
  285. if (workSpace.isGroupedByDate()) {
  286. return workSpace._getGroupCount() * cellWidth
  287. }
  288. return cellWidth
  289. },
  290. getEndDate: function(appointmentData, skipNormalize) {
  291. return this._getEndDate(appointmentData, skipNormalize)
  292. },
  293. getRenderingStrategy: function() {
  294. return this._getAppointmentsRenderingStrategy()
  295. },
  296. needCorrectAppointmentDates: function() {
  297. return this.getRenderingStrategyInstance().needCorrectAppointmentDates()
  298. },
  299. getRenderingStrategyDirection: function() {
  300. return this.getRenderingStrategyInstance().getDirection()
  301. },
  302. getWorkSpaceDateTableOffset: function() {
  303. return this.getWorkSpaceDateTableOffset()
  304. },
  305. correctAppointmentCoordinates: function(options) {
  306. var isAllDay = options.allDay;
  307. var containerSign = options.isFixedContainer ? -1 : 1;
  308. var scrollTop = this.getWorkSpaceScrollableScrollTop(isAllDay);
  309. var allDayPanelTopOffset = !isAllDay ? this.getWorkSpaceAllDayOffset() : 0;
  310. var headerHeight = this.getWorkSpaceHeaderPanelHeight();
  311. var scrollLeft = this.getWorkSpaceScrollableScrollLeft();
  312. var tableLeftOffset = this.getWorkSpaceDateTableOffset();
  313. var topOffset = -scrollTop + allDayPanelTopOffset + headerHeight;
  314. var leftOffset = -scrollLeft - tableLeftOffset;
  315. options.callback({
  316. top: options.coordinates.top + containerSign * topOffset,
  317. left: options.coordinates.left + containerSign * leftOffset
  318. })
  319. },
  320. allDayPanelToggled: function() {
  321. this._appointments.updateDraggablesBoundOffsets()
  322. },
  323. formatDates: function(options) {
  324. var startDate = options.startDate;
  325. var endDate = options.endDate;
  326. var formatType = options.formatType;
  327. var formatTypes = {
  328. DATETIME: function() {
  329. var dateTimeFormat = "mediumdatemediumtime";
  330. var startDateString = _date4.default.format(startDate, dateTimeFormat) + " - ";
  331. var endDateString = startDate.getDate() === endDate.getDate() ? _date4.default.format(endDate, "shorttime") : _date4.default.format(endDate, dateTimeFormat);
  332. return startDateString + endDateString
  333. },
  334. TIME: function() {
  335. return _date4.default.format(startDate, "shorttime") + " - " + _date4.default.format(endDate, "shorttime")
  336. },
  337. DATE: function() {
  338. var dateTimeFormat = "monthAndDay";
  339. var startDateString = _date4.default.format(startDate, dateTimeFormat);
  340. var isDurationMoreThanDay = endDate.getTime() - startDate.getTime() > toMs("day");
  341. var endDateString = isDurationMoreThanDay || endDate.getDate() !== startDate.getDate() ? " - " + _date4.default.format(endDate, dateTimeFormat) : "";
  342. return startDateString + endDateString
  343. }
  344. };
  345. options.callback(formatTypes[formatType]())
  346. },
  347. getFullWeekAppointmentWidth: function(options) {
  348. var groupIndex = options.groupIndex;
  349. var groupWidth = this._workSpace.getGroupWidth(groupIndex);
  350. options.callback(groupWidth)
  351. },
  352. getMaxAppointmentWidth: function(options) {
  353. var cellCountToLastViewDate = this._workSpace.getCellCountToLastViewDate(options.date);
  354. options.callback(cellCountToLastViewDate * this._workSpace.getCellWidth())
  355. },
  356. updateAppointmentStartDate: function(options) {
  357. var appointment = options.appointment;
  358. var firstViewDate = this._workSpace.getStartViewDate();
  359. var startDate = new Date(options.startDate);
  360. var startDayHour = this._getCurrentViewOption("startDayHour");
  361. var updatedStartDate;
  362. if (this.appointmentTakesAllDay(appointment)) {
  363. updatedStartDate = _date2.default.normalizeDate(startDate, firstViewDate)
  364. } else {
  365. if (startDate < firstViewDate) {
  366. startDate = firstViewDate
  367. }
  368. updatedStartDate = _date2.default.normalizeDate(options.startDate, new Date(startDate))
  369. }
  370. updatedStartDate = _date2.default.roundDateByStartDayHour(updatedStartDate, startDayHour);
  371. options.callback(updatedStartDate)
  372. },
  373. updateAppointmentEndDate: function(options) {
  374. var endDate = options.endDate;
  375. var endDayHour = this._getCurrentViewOption("endDayHour");
  376. var startDayHour = this._getCurrentViewOption("startDayHour");
  377. var updatedEndDate = endDate;
  378. if (endDate.getHours() >= endDayHour) {
  379. updatedEndDate.setHours(endDayHour, 0, 0, 0)
  380. } else {
  381. if (!options.isSameDate && startDayHour > 0 && 60 * endDate.getHours() + endDate.getMinutes() < 60 * startDayHour) {
  382. updatedEndDate = new Date(updatedEndDate.getTime() - toMs("day"));
  383. updatedEndDate.setHours(endDayHour, 0, 0, 0)
  384. }
  385. }
  386. options.callback(updatedEndDate)
  387. },
  388. renderCompactAppointments: function(options) {
  389. this._compactAppointmentsHelper.render(options)
  390. },
  391. clearCompactAppointments: function() {
  392. this._compactAppointmentsHelper.clear()
  393. },
  394. supportCompactDropDownAppointments: function() {
  395. return this._workSpace._supportCompactDropDownAppointments()
  396. },
  397. getGroupCount: function() {
  398. return this._workSpace._getGroupCount()
  399. },
  400. mapAppointmentFields: function(config) {
  401. var result = {
  402. appointmentData: config.itemData,
  403. appointmentElement: config.itemElement
  404. };
  405. if (config.itemData) {
  406. result.targetedAppointmentData = this.fire("getTargetedAppointmentData", config.itemData, config.itemElement)
  407. }
  408. return result
  409. },
  410. getOffsetByAllDayPanel: function(groupIndex) {
  411. return this._workSpace._getOffsetByAllDayPanel(groupIndex)
  412. },
  413. getGroupTop: function(groupIndex) {
  414. return this._workSpace._getGroupTop(groupIndex)
  415. },
  416. updateResizableArea: function() {
  417. var $allResizableElements = this.$element().find(".dx-scheduler-appointment.dx-resizable");
  418. var horizontalResizables = (0, _common.grep)($allResizableElements, function(el) {
  419. var $el = (0, _renderer2.default)(el);
  420. var resizableInst = $el.dxResizable("instance");
  421. var area = resizableInst.option("area");
  422. return (0, _array.inArray)(resizableInst.option("handles"), ["right left", "left right"]) > -1 && _type2.default.isPlainObject(area)
  423. });
  424. (0, _iterator.each)(horizontalResizables, function(_, el) {
  425. var $el = (0, _renderer2.default)(el);
  426. var position = _translator2.default.locate($el);
  427. var appointmentData = this._appointments._getItemData($el);
  428. var area = this._appointments._calculateResizableArea({
  429. left: position.left
  430. }, appointmentData);
  431. $el.dxResizable("instance").option("area", area)
  432. }.bind(this))
  433. },
  434. recurrenceEditorVisibilityChanged: function(visible) {
  435. this.recurrenceEditorVisibilityChanged(visible)
  436. },
  437. resizePopup: function() {
  438. this.resizePopup()
  439. },
  440. getField: function(field, obj) {
  441. if (!_type2.default.isDefined(this._dataAccessors.getter[field])) {
  442. return
  443. }
  444. return this._dataAccessors.getter[field](obj)
  445. },
  446. setField: function(field, obj, value) {
  447. if (!_type2.default.isDefined(this._dataAccessors.setter[field])) {
  448. return
  449. }
  450. var splitExprStr = this.option(field + "Expr").split(".");
  451. var rootField = splitExprStr[0];
  452. if (void 0 === obj[rootField] && splitExprStr.length > 1) {
  453. var emptyChain = function(arr) {
  454. var result = {};
  455. var tmp = result;
  456. var arrLength = arr.length - 1;
  457. for (var i = 1; i < arrLength; i++) {
  458. tmp = tmp[arr[i]] = {}
  459. }
  460. return result
  461. }(splitExprStr);
  462. obj[rootField] = emptyChain
  463. }
  464. this._dataAccessors.setter[field](obj, value);
  465. return obj
  466. },
  467. prerenderFilter: function() {
  468. var dateRange = this.getWorkSpace().getDateRange();
  469. var resources = this._resourcesManager.getResourcesData();
  470. var allDay;
  471. if (!this.option("showAllDayPanel") && this._workSpace.supportAllDayRow()) {
  472. allDay = false
  473. }
  474. return this._appointmentModel.filterLoadedAppointments({
  475. startDayHour: this._getCurrentViewOption("startDayHour"),
  476. endDayHour: this._getCurrentViewOption("endDayHour"),
  477. min: dateRange[0],
  478. max: dateRange[1],
  479. resources: resources,
  480. allDay: allDay,
  481. firstDayOfWeek: this.getFirstDayOfWeek(),
  482. recurrenceException: this._getRecurrenceException.bind(this)
  483. }, this._subscribes.convertDateByTimezone.bind(this))
  484. },
  485. dayHasAppointment: function(day, appointment, trimTime) {
  486. return this.dayHasAppointment(day, appointment, trimTime)
  487. },
  488. createResourcesTree: function() {
  489. return this._resourcesManager.createResourcesTree(this._loadedResources)
  490. },
  491. getResourceTreeLeaves: function(tree, appointmentResources) {
  492. return this._resourcesManager.getResourceTreeLeaves(tree, appointmentResources)
  493. },
  494. createReducedResourcesTree: function() {
  495. var tree = this._resourcesManager.createResourcesTree(this._loadedResources);
  496. return this._resourcesManager.reduceResourcesTree(tree, this.getFilteredItems())
  497. },
  498. groupAppointmentsByResources: function(appointments) {
  499. var result = {
  500. 0: appointments
  501. };
  502. var groups = this._getCurrentViewOption("groups");
  503. if (groups && groups.length && this._resourcesManager.getResourcesData().length) {
  504. result = this._resourcesManager.groupAppointmentsByResources(appointments, this._loadedResources)
  505. }
  506. var totalResourceCount = 0;
  507. (0, _iterator.each)(this._loadedResources, function(i, resource) {
  508. if (!i) {
  509. totalResourceCount = resource.items.length
  510. } else {
  511. totalResourceCount *= resource.items.length
  512. }
  513. });
  514. for (var j = 0; j < totalResourceCount; j++) {
  515. var index = j.toString();
  516. if (result[index]) {
  517. continue
  518. }
  519. result[index] = []
  520. }
  521. return result
  522. },
  523. getAgendaRows: function(options) {
  524. var renderingStrategy = this._layoutManager.getRenderingStrategyInstance();
  525. var calculateRows = renderingStrategy.calculateRows.bind(renderingStrategy);
  526. var d = new _deferred.Deferred;
  527. function rowsCalculated(appointments) {
  528. var result = calculateRows(appointments, options.agendaDuration, options.currentDate);
  529. this._dataSourceLoadedCallback.remove(rowsCalculated);
  530. d.resolve(result)
  531. }
  532. this._dataSourceLoadedCallback.add(rowsCalculated);
  533. return d.promise()
  534. },
  535. getAgendaVerticalStepHeight: function() {
  536. return this.getWorkSpace().getAgendaVerticalStepHeight()
  537. },
  538. getAgendaDuration: function() {
  539. return this._getCurrentViewOption("agendaDuration")
  540. },
  541. getStartViewDate: function() {
  542. return this.getStartViewDate()
  543. },
  544. getEndViewDate: function() {
  545. return this.getEndViewDate()
  546. },
  547. getMaxAppointmentsPerCell: function() {
  548. return this.getMaxAppointmentsPerCell()
  549. },
  550. forceMaxAppointmentPerCell: function() {
  551. return this.forceMaxAppointmentPerCell()
  552. },
  553. agendaIsReady: function(rows, innerRowOffset, outerRowOffset) {
  554. var $appts = this.getAppointmentsInstance()._itemElements();
  555. var total = 0;
  556. $appts.css("marginBottom", innerRowOffset);
  557. var applyOffset = function(_, count) {
  558. var index = count + total - 1;
  559. $appts.eq(index).css("marginBottom", outerRowOffset);
  560. total += count
  561. };
  562. for (var i = 0; i < rows.length; i++) {
  563. (0, _iterator.each)(rows[i], applyOffset)
  564. }
  565. },
  566. getTimezone: function() {
  567. return this._getTimezoneOffsetByOption()
  568. },
  569. getClientTimezoneOffset: function(date) {
  570. date = date || new Date;
  571. return _uiScheduler2.default.getClientTimezoneOffset(date)
  572. },
  573. convertDateByTimezone: function(date, appointmentTimezone) {
  574. date = new Date(date);
  575. var tzOffsets = this._subscribes.getComplexOffsets(this, date, appointmentTimezone);
  576. date = this._subscribes.translateDateToAppointmentTimeZone(date, tzOffsets);
  577. date = this._subscribes.translateDateToCommonTimeZone(date, tzOffsets);
  578. return date
  579. },
  580. convertDateByTimezoneBack: function(date, appointmentTimezone) {
  581. date = new Date(date);
  582. var tzOffsets = this._subscribes.getComplexOffsets(this, date, appointmentTimezone);
  583. date = this._subscribes.translateDateToAppointmentTimeZone(date, tzOffsets, true);
  584. date = this._subscribes.translateDateToCommonTimeZone(date, tzOffsets, true);
  585. return date
  586. },
  587. translateDateToAppointmentTimeZone: function(date, offsets, back) {
  588. var operation = back ? -1 : 1;
  589. var dateInUTC = date.getTime() - operation * offsets.client * toMs("hour");
  590. return new Date(dateInUTC + operation * offsets.appointment * toMs("hour"))
  591. },
  592. translateDateToCommonTimeZone: function(date, offsets, back) {
  593. var operation = back ? -1 : 1;
  594. if ("number" === typeof offsets.common) {
  595. var offset = offsets.common - offsets.appointment;
  596. var hoursOffset = (offset < 0 ? -1 : 1) * Math.floor(Math.abs(offset));
  597. var minutesOffset = offset % 1;
  598. date.setHours(date.getHours() + operation * hoursOffset);
  599. date.setMinutes(date.getMinutes() + operation * minutesOffset * MINUTES_IN_HOUR)
  600. }
  601. return date
  602. },
  603. getComplexOffsets: function(scheduler, date, appointmentTimezone) {
  604. var clientTimezoneOffset = -this.getClientTimezoneOffset(date) / toMs("hour");
  605. var commonTimezoneOffset = scheduler._getTimezoneOffsetByOption(date);
  606. var appointmentTimezoneOffset = scheduler._calculateTimezoneByValue(appointmentTimezone, date);
  607. if ("number" !== typeof appointmentTimezoneOffset) {
  608. appointmentTimezoneOffset = clientTimezoneOffset
  609. }
  610. return {
  611. client: clientTimezoneOffset,
  612. common: commonTimezoneOffset,
  613. appointment: appointmentTimezoneOffset
  614. }
  615. },
  616. getDaylightOffset: function(startDate, endDate) {
  617. return startDate.getTimezoneOffset() - endDate.getTimezoneOffset()
  618. },
  619. getTimezonesDisplayName: function() {
  620. return _uiScheduler2.default.getTimezonesDisplayName()
  621. },
  622. getTimezoneDisplayNameById: function(id) {
  623. return _uiScheduler2.default.getTimezoneDisplayNameById(id)
  624. },
  625. getSimilarTimezones: function(id) {
  626. return _uiScheduler2.default.getSimilarTimezones(id)
  627. },
  628. getTimezonesIdsByDisplayName: function(displayName) {
  629. return _uiScheduler2.default.getTimezonesIdsByDisplayName(displayName)
  630. },
  631. getTargetedAppointmentData: function(appointmentData, appointmentElement) {
  632. var $appointmentElement = (0, _renderer2.default)(appointmentElement);
  633. var appointmentIndex = $appointmentElement.data(this._appointments._itemIndexKey());
  634. var recurringData = this._getSingleAppointmentData(appointmentData, {
  635. skipDateCalculation: true,
  636. $appointment: $appointmentElement,
  637. skipHoursProcessing: true
  638. });
  639. var result = {};
  640. (0, _extend.extend)(true, result, appointmentData, recurringData);
  641. this._convertDatesByTimezoneBack(false, result);
  642. appointmentElement && this.setTargetedAppointmentResources(result, appointmentElement, appointmentIndex);
  643. return result
  644. },
  645. getAppointmentDurationInMs: function(options) {
  646. var startDate = options.startDate;
  647. var endDate = options.endDate;
  648. var allDay = options.allDay;
  649. var appointmentDuration = endDate.getTime() - startDate.getTime();
  650. var dayDuration = toMs("day");
  651. var visibleDayDuration = this._workSpace.getVisibleDayDuration();
  652. var result = 0;
  653. if (allDay) {
  654. var ceilQuantityOfDays = Math.ceil(appointmentDuration / dayDuration);
  655. result = ceilQuantityOfDays * visibleDayDuration
  656. } else {
  657. var isDifferentDate = !_date2.default.sameDate(startDate, new Date(endDate.getTime() - 1));
  658. var floorQuantityOfDays = Math.floor(appointmentDuration / dayDuration);
  659. var tailDuration;
  660. if (isDifferentDate) {
  661. var startDateEndHour = new Date(new Date(startDate).setHours(this.option("endDayHour"), 0, 0));
  662. var hiddenDayDuration = dayDuration - visibleDayDuration - (startDate.getTime() > startDateEndHour.getTime() ? startDate.getTime() - startDateEndHour.getTime() : 0);
  663. tailDuration = appointmentDuration - (floorQuantityOfDays ? floorQuantityOfDays * dayDuration : hiddenDayDuration);
  664. var startDayTime = this.option("startDayHour") * toMs("hour");
  665. var endPartDuration = endDate - _date2.default.trimTime(endDate);
  666. if (endPartDuration < startDayTime) {
  667. if (floorQuantityOfDays) {
  668. tailDuration -= hiddenDayDuration
  669. }
  670. tailDuration += startDayTime - endPartDuration
  671. }
  672. } else {
  673. tailDuration = appointmentDuration % dayDuration
  674. }
  675. if (tailDuration > visibleDayDuration) {
  676. tailDuration = visibleDayDuration
  677. }
  678. result = floorQuantityOfDays * visibleDayDuration + tailDuration || toMs("minute")
  679. }
  680. options.callback(result)
  681. },
  682. fixWrongEndDate: function(appointment, startDate, endDate) {
  683. return this._appointmentModel.fixWrongEndDate(appointment, startDate, endDate)
  684. },
  685. getEndDayHour: function() {
  686. return this._workSpace.option("endDayHour") || this.option("endDayHour")
  687. },
  688. getStartDayHour: function() {
  689. return this._workSpace.option("startDayHour") || this.option("startDayHour")
  690. },
  691. isAdaptive: function() {
  692. return this.option("adaptivityEnabled")
  693. }
  694. };
  695. module.exports = subscribes;