ui.scheduler.js 89 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941
  1. /**
  2. * DevExtreme (ui/scheduler/ui.scheduler.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 _callbacks = require("../../core/utils/callbacks");
  13. var _callbacks2 = _interopRequireDefault(_callbacks);
  14. var _translator = require("../../animation/translator");
  15. var _translator2 = _interopRequireDefault(_translator);
  16. var _ui = require("../widget/ui.errors");
  17. var _ui2 = _interopRequireDefault(_ui);
  18. var _window = require("../../core/utils/window");
  19. var _window2 = _interopRequireDefault(_window);
  20. var _dialog = require("../dialog");
  21. var _dialog2 = _interopRequireDefault(_dialog);
  22. var _utils = require("./utils.recurrence");
  23. var _utils2 = _interopRequireDefault(_utils);
  24. var _dom = require("../../core/utils/dom");
  25. var _dom2 = _interopRequireDefault(_dom);
  26. var _date = require("../../core/utils/date");
  27. var _date2 = _interopRequireDefault(_date);
  28. var _object = require("../../core/utils/object");
  29. var _object2 = _interopRequireDefault(_object);
  30. var _iterator = require("../../core/utils/iterator");
  31. var _extend = require("../../core/utils/extend");
  32. var _array = require("../../core/utils/array");
  33. var _common = require("../../core/utils/common");
  34. var _type = require("../../core/utils/type");
  35. var _type2 = _interopRequireDefault(_type);
  36. var _devices = require("../../core/devices");
  37. var _devices2 = _interopRequireDefault(_devices);
  38. var _config = require("../../core/config");
  39. var _config2 = _interopRequireDefault(_config);
  40. var _component_registrator = require("../../core/component_registrator");
  41. var _component_registrator2 = _interopRequireDefault(_component_registrator);
  42. var _message = require("../../localization/message");
  43. var _message2 = _interopRequireDefault(_message);
  44. var _date_serialization = require("../../core/utils/date_serialization");
  45. var _date_serialization2 = _interopRequireDefault(_date_serialization);
  46. var _date3 = require("../../localization/date");
  47. var _date4 = _interopRequireDefault(_date3);
  48. var _ui3 = require("../widget/ui.widget");
  49. var _ui4 = _interopRequireDefault(_ui3);
  50. var _uiScheduler = require("./ui.scheduler.subscribes");
  51. var _uiScheduler2 = _interopRequireDefault(_uiScheduler);
  52. var _function_template = require("../widget/function_template");
  53. var _function_template2 = _interopRequireDefault(_function_template);
  54. var _desktopTooltipStrategy = require("./tooltip_strategies/desktopTooltipStrategy");
  55. var _mobileTooltipStrategy = require("./tooltip_strategies/mobileTooltipStrategy");
  56. var _uiScheduler3 = require("./ui.scheduler.header");
  57. var _uiScheduler4 = _interopRequireDefault(_uiScheduler3);
  58. var _uiScheduler5 = require("./workspaces/ui.scheduler.work_space_day");
  59. var _uiScheduler6 = _interopRequireDefault(_uiScheduler5);
  60. var _uiScheduler7 = require("./workspaces/ui.scheduler.work_space_week");
  61. var _uiScheduler8 = _interopRequireDefault(_uiScheduler7);
  62. var _uiScheduler9 = require("./workspaces/ui.scheduler.work_space_work_week");
  63. var _uiScheduler10 = _interopRequireDefault(_uiScheduler9);
  64. var _uiScheduler11 = require("./workspaces/ui.scheduler.work_space_month");
  65. var _uiScheduler12 = _interopRequireDefault(_uiScheduler11);
  66. var _uiScheduler13 = require("./workspaces/ui.scheduler.timeline_day");
  67. var _uiScheduler14 = _interopRequireDefault(_uiScheduler13);
  68. var _uiScheduler15 = require("./workspaces/ui.scheduler.timeline_week");
  69. var _uiScheduler16 = _interopRequireDefault(_uiScheduler15);
  70. var _uiScheduler17 = require("./workspaces/ui.scheduler.timeline_work_week");
  71. var _uiScheduler18 = _interopRequireDefault(_uiScheduler17);
  72. var _uiScheduler19 = require("./workspaces/ui.scheduler.timeline_month");
  73. var _uiScheduler20 = _interopRequireDefault(_uiScheduler19);
  74. var _uiScheduler21 = require("./workspaces/ui.scheduler.agenda");
  75. var _uiScheduler22 = _interopRequireDefault(_uiScheduler21);
  76. var _uiScheduler23 = require("./ui.scheduler.resource_manager");
  77. var _uiScheduler24 = _interopRequireDefault(_uiScheduler23);
  78. var _uiScheduler25 = require("./ui.scheduler.appointment_model");
  79. var _uiScheduler26 = _interopRequireDefault(_uiScheduler25);
  80. var _uiScheduler27 = require("./ui.scheduler.appointments");
  81. var _uiScheduler28 = _interopRequireDefault(_uiScheduler27);
  82. var _uiSchedulerAppointments = require("./ui.scheduler.appointments.layout_manager");
  83. var _uiSchedulerAppointments2 = _interopRequireDefault(_uiSchedulerAppointments);
  84. var _compactAppointmentsHelper = require("./compactAppointmentsHelper");
  85. var _uiScheduler29 = require("./timezones/ui.scheduler.timezones");
  86. var _uiScheduler30 = _interopRequireDefault(_uiScheduler29);
  87. var _async_template_mixin = require("../shared/async_template_mixin");
  88. var _async_template_mixin2 = _interopRequireDefault(_async_template_mixin);
  89. var _data_helper = require("../../data_helper");
  90. var _data_helper2 = _interopRequireDefault(_data_helper);
  91. var _ui5 = require("./ui.loading");
  92. var _ui6 = _interopRequireDefault(_ui5);
  93. var _uiScheduler31 = require("./ui.scheduler.appointment_form");
  94. var _uiScheduler32 = _interopRequireDefault(_uiScheduler31);
  95. var _popup = require("../popup");
  96. var _popup2 = _interopRequireDefault(_popup);
  97. var _deferred = require("../../core/utils/deferred");
  98. var _deferred2 = _interopRequireDefault(_deferred);
  99. var _empty_template = require("../widget/empty_template");
  100. var _empty_template2 = _interopRequireDefault(_empty_template);
  101. var _bindable_template = require("../widget/bindable_template");
  102. var _bindable_template2 = _interopRequireDefault(_bindable_template);
  103. var _themes = require("../themes");
  104. var _themes2 = _interopRequireDefault(_themes);
  105. var _browser = require("../../core/utils/browser");
  106. var _browser2 = _interopRequireDefault(_browser);
  107. var _support = require("../../core/utils/support");
  108. function _interopRequireDefault(obj) {
  109. return obj && obj.__esModule ? obj : {
  110. "default": obj
  111. }
  112. }
  113. var when = _deferred2.default.when;
  114. var Deferred = _deferred2.default.Deferred;
  115. var toMs = _date2.default.dateToMilliseconds;
  116. var WIDGET_CLASS = "dx-scheduler";
  117. var WIDGET_SMALL_CLASS = "".concat(WIDGET_CLASS, "-small");
  118. var WIDGET_ADAPTIVE_CLASS = "".concat(WIDGET_CLASS, "-adaptive");
  119. var WIDGET_WIN_NO_TOUCH_CLASS = "".concat(WIDGET_CLASS, "-win-no-touch");
  120. var WIDGET_READONLY_CLASS = "".concat(WIDGET_CLASS, "-readonly");
  121. var APPOINTMENT_POPUP_CLASS = "".concat(WIDGET_CLASS, "-appointment-popup");
  122. var RECURRENCE_EDITOR_ITEM_CLASS = "".concat(WIDGET_CLASS, "-recurrence-rule-item");
  123. var RECURRENCE_EDITOR_OPENED_ITEM_CLASS = "".concat(WIDGET_CLASS, "-recurrence-rule-item-opened");
  124. var WIDGET_SMALL_WIDTH = 400;
  125. var APPOINTMENT_POPUP_WIDTH = 610;
  126. var APPOINTMENT_POPUP_FULLSCREEN_WINDOW_WIDTH = 768;
  127. var TOOLBAR_ITEM_AFTER_LOCATION = "after";
  128. var TOOLBAR_ITEM_BEFORE_LOCATION = "before";
  129. var FULL_DATE_FORMAT = "yyyyMMddTHHmmss";
  130. var UTC_FULL_DATE_FORMAT = FULL_DATE_FORMAT + "Z";
  131. var VIEWS_CONFIG = {
  132. day: {
  133. workSpace: _uiScheduler6.default,
  134. renderingStrategy: "vertical"
  135. },
  136. week: {
  137. workSpace: _uiScheduler8.default,
  138. renderingStrategy: "vertical"
  139. },
  140. workWeek: {
  141. workSpace: _uiScheduler10.default,
  142. renderingStrategy: "vertical"
  143. },
  144. month: {
  145. workSpace: _uiScheduler12.default,
  146. renderingStrategy: "horizontalMonth"
  147. },
  148. timelineDay: {
  149. workSpace: _uiScheduler14.default,
  150. renderingStrategy: "horizontal"
  151. },
  152. timelineWeek: {
  153. workSpace: _uiScheduler16.default,
  154. renderingStrategy: "horizontal"
  155. },
  156. timelineWorkWeek: {
  157. workSpace: _uiScheduler18.default,
  158. renderingStrategy: "horizontal"
  159. },
  160. timelineMonth: {
  161. workSpace: _uiScheduler20.default,
  162. renderingStrategy: "horizontalMonthLine"
  163. },
  164. agenda: {
  165. workSpace: _uiScheduler22.default,
  166. renderingStrategy: "agenda"
  167. }
  168. };
  169. var Scheduler = _ui4.default.inherit({
  170. _getDefaultOptions: function() {
  171. return (0, _extend.extend)(this.callBase(), {
  172. views: ["day", "week"],
  173. currentView: "day",
  174. currentDate: _date2.default.trimTime(new Date),
  175. min: void 0,
  176. max: void 0,
  177. dateSerializationFormat: void 0,
  178. firstDayOfWeek: void 0,
  179. groups: [],
  180. resources: [],
  181. dataSource: null,
  182. customizeDateNavigatorText: void 0,
  183. appointmentTemplate: "item",
  184. dropDownAppointmentTemplate: "dropDownAppointment",
  185. appointmentCollectorTemplate: "appointmentCollector",
  186. dataCellTemplate: null,
  187. timeCellTemplate: null,
  188. resourceCellTemplate: null,
  189. dateCellTemplate: null,
  190. startDayHour: 0,
  191. endDayHour: 24,
  192. editing: {
  193. allowAdding: true,
  194. allowDeleting: true,
  195. allowDragging: true,
  196. allowResizing: true,
  197. allowUpdating: true
  198. },
  199. showAllDayPanel: true,
  200. showCurrentTimeIndicator: true,
  201. shadeUntilCurrentTime: false,
  202. indicatorUpdateInterval: 3e5,
  203. indicatorTime: void 0,
  204. recurrenceEditMode: "dialog",
  205. cellDuration: 30,
  206. maxAppointmentsPerCell: "auto",
  207. selectedCellData: [],
  208. groupByDate: false,
  209. onAppointmentRendered: null,
  210. onAppointmentClick: null,
  211. onAppointmentDblClick: null,
  212. onAppointmentContextMenu: null,
  213. onCellClick: null,
  214. onCellContextMenu: null,
  215. onAppointmentAdding: null,
  216. onAppointmentAdded: null,
  217. onAppointmentUpdating: null,
  218. onAppointmentUpdated: null,
  219. onAppointmentDeleting: null,
  220. onAppointmentDeleted: null,
  221. onAppointmentFormOpening: null,
  222. appointmentTooltipTemplate: "appointmentTooltip",
  223. appointmentPopupTemplate: "appointmentPopup",
  224. crossScrollingEnabled: false,
  225. useDropDownViewSwitcher: false,
  226. startDateExpr: "startDate",
  227. endDateExpr: "endDate",
  228. textExpr: "text",
  229. descriptionExpr: "description",
  230. allDayExpr: "allDay",
  231. recurrenceRuleExpr: "recurrenceRule",
  232. recurrenceExceptionExpr: "recurrenceException",
  233. remoteFiltering: false,
  234. timeZone: "",
  235. startDateTimeZoneExpr: "startDateTimeZone",
  236. endDateTimeZoneExpr: "endDateTimeZone",
  237. noDataText: _message2.default.format("dxCollectionWidget-noDataText"),
  238. adaptivityEnabled: false,
  239. allowMultipleCellSelection: true,
  240. _appointmentTooltipOffset: {
  241. x: 0,
  242. y: 0
  243. },
  244. _appointmentTooltipButtonsPosition: "bottom",
  245. _appointmentTooltipOpenButtonText: _message2.default.format("dxScheduler-openAppointment"),
  246. _dropDownButtonIcon: "overflow",
  247. _appointmentCountPerCell: 2,
  248. _collectorOffset: 0,
  249. _appointmentOffset: 26
  250. })
  251. },
  252. _defaultOptionsRules: function() {
  253. return this.callBase().concat([{
  254. device: function() {
  255. return "desktop" === _devices2.default.real().deviceType && !_devices2.default.isSimulator()
  256. },
  257. options: {
  258. focusStateEnabled: true
  259. }
  260. }, {
  261. device: function() {
  262. return !_devices2.default.current().generic
  263. },
  264. options: {
  265. useDropDownViewSwitcher: true,
  266. editing: {
  267. allowDragging: false,
  268. allowResizing: false
  269. }
  270. }
  271. }, {
  272. device: function() {
  273. return _themes2.default.isMaterial()
  274. },
  275. options: {
  276. useDropDownViewSwitcher: true,
  277. dateCellTemplate: function(data, index, element) {
  278. var text = data.text;
  279. text.split(" ").forEach(function(text, index) {
  280. var span = (0, _renderer2.default)("<span>").text(text).addClass("dx-scheduler-header-panel-cell-date");
  281. (0, _renderer2.default)(element).append(span);
  282. if (!index) {
  283. (0, _renderer2.default)(element).append(" ")
  284. }
  285. })
  286. },
  287. _appointmentTooltipOffset: {
  288. x: 0,
  289. y: 11
  290. },
  291. _appointmentTooltipButtonsPosition: "top",
  292. _appointmentTooltipOpenButtonText: null,
  293. _dropDownButtonIcon: "chevrondown",
  294. _appointmentCountPerCell: 1,
  295. _collectorOffset: 20,
  296. _appointmentOffset: 30
  297. }
  298. }])
  299. },
  300. _setDeprecatedOptions: function() {
  301. this.callBase();
  302. (0, _extend.extend)(this._deprecatedOptions, {
  303. onAppointmentFormCreated: {
  304. since: "18.2",
  305. alias: "onAppointmentFormOpening"
  306. }
  307. })
  308. },
  309. _postponeDataSourceLoading: function(promise) {
  310. this.postponedOperations.add("_reloadDataSource", this._reloadDataSource.bind(this), promise)
  311. },
  312. _postponeResourceLoading: function() {
  313. var _this = this;
  314. var whenLoaded = this.postponedOperations.add("_loadResources", function() {
  315. return _this._loadResources()
  316. });
  317. var resolveCallbacks = new Deferred;
  318. whenLoaded.done(function(resources) {
  319. resolveCallbacks.resolve(resources)
  320. });
  321. this._postponeDataSourceLoading(whenLoaded);
  322. return resolveCallbacks.promise()
  323. },
  324. _optionChanged: function(args) {
  325. var _this2 = this;
  326. var value = args.value;
  327. var name = args.name;
  328. switch (args.name) {
  329. case "customizeDateNavigatorText":
  330. this._updateOption("header", name, value);
  331. break;
  332. case "firstDayOfWeek":
  333. this._updateOption("workSpace", name, value);
  334. this._updateOption("header", name, value);
  335. break;
  336. case "currentDate":
  337. value = this._dateOption(name);
  338. value = _date2.default.trimTime(new Date(value));
  339. this.option("selectedCellData", []);
  340. this._workSpace.option(name, new Date(value));
  341. this._header.option(name, new Date(value));
  342. this._header.option("displayedDate", this._workSpace._getViewStartByOptions());
  343. this._appointments.option("items", []);
  344. this._filterAppointmentsByDate();
  345. this._postponeDataSourceLoading();
  346. break;
  347. case "dataSource":
  348. this._initDataSource();
  349. this._customizeStoreLoadOptions();
  350. this._appointmentModel.setDataSource(this._dataSource);
  351. this._postponeResourceLoading().done(function(resources) {
  352. _this2._filterAppointmentsByDate();
  353. _this2._updateOption("workSpace", "showAllDayPanel", _this2.option("showAllDayPanel"))
  354. });
  355. break;
  356. case "min":
  357. case "max":
  358. value = this._dateOption(name);
  359. this._updateOption("header", name, new Date(value));
  360. this._updateOption("workSpace", name, new Date(value));
  361. break;
  362. case "views":
  363. this._processCurrentView();
  364. if (this._getCurrentViewOptions()) {
  365. this.repaint()
  366. } else {
  367. this._header.option(name, value)
  368. }
  369. break;
  370. case "useDropDownViewSwitcher":
  371. this._header.option(name, value);
  372. break;
  373. case "currentView":
  374. this._processCurrentView();
  375. this.getLayoutManager().initRenderingStrategy(this._getAppointmentsRenderingStrategy());
  376. this._appointments.option({
  377. items: [],
  378. allowDrag: this._allowDragging(),
  379. allowResize: this._allowResizing(),
  380. itemTemplate: this._getAppointmentTemplate("appointmentTemplate")
  381. });
  382. this._postponeResourceLoading().done(function(resources) {
  383. _this2._refreshWorkSpace(resources);
  384. _this2._updateHeader();
  385. _this2._filterAppointmentsByDate();
  386. _this2._appointments.option("allowAllDayResize", "day" !== value)
  387. });
  388. break;
  389. case "appointmentTemplate":
  390. this._appointments.option("itemTemplate", value);
  391. break;
  392. case "dateCellTemplate":
  393. case "resourceCellTemplate":
  394. case "dataCellTemplate":
  395. case "timeCellTemplate":
  396. this._updateOption("workSpace", name, value);
  397. this.repaint();
  398. break;
  399. case "groups":
  400. this._postponeResourceLoading().done(function(resources) {
  401. _this2._refreshWorkSpace(resources);
  402. _this2._filterAppointmentsByDate()
  403. });
  404. break;
  405. case "resources":
  406. this._resourcesManager.setResources(this.option("resources"));
  407. this._appointmentModel.setDataAccessors(this._combineDataAccessors());
  408. this._postponeResourceLoading().done(function(resources) {
  409. _this2._appointments.option("items", []);
  410. _this2._refreshWorkSpace(resources);
  411. _this2._filterAppointmentsByDate()
  412. });
  413. break;
  414. case "startDayHour":
  415. case "endDayHour":
  416. this._appointments.option("items", []);
  417. this._updateOption("workSpace", name, value);
  418. this._appointments.repaint();
  419. this._filterAppointmentsByDate();
  420. this._postponeDataSourceLoading();
  421. break;
  422. case "onAppointmentAdding":
  423. case "onAppointmentAdded":
  424. case "onAppointmentUpdating":
  425. case "onAppointmentUpdated":
  426. case "onAppointmentDeleting":
  427. case "onAppointmentDeleted":
  428. case "onAppointmentFormOpening":
  429. this._actions[name] = this._createActionByOption(name);
  430. break;
  431. case "onAppointmentRendered":
  432. this._appointments.option("onItemRendered", this._getAppointmentRenderedAction());
  433. break;
  434. case "onAppointmentClick":
  435. this._appointments.option("onItemClick", this._createActionByOption(name));
  436. break;
  437. case "onAppointmentDblClick":
  438. this._appointments.option(name, this._createActionByOption(name));
  439. break;
  440. case "onAppointmentContextMenu":
  441. this._appointments.option("onItemContextMenu", this._createActionByOption(name));
  442. break;
  443. case "noDataText":
  444. case "allowMultipleCellSelection":
  445. case "selectedCellData":
  446. case "accessKey":
  447. case "onCellClick":
  448. this._workSpace.option(name, value);
  449. break;
  450. case "onCellContextMenu":
  451. this._workSpace.option(name, value);
  452. break;
  453. case "crossScrollingEnabled":
  454. this._postponeResourceLoading().done(function(resources) {
  455. _this2._appointments.option("items", []);
  456. _this2._refreshWorkSpace(resources);
  457. if (_this2._readyToRenderAppointments) {
  458. _this2._appointments.option("items", _this2._getAppointmentsToRepaint())
  459. }
  460. });
  461. break;
  462. case "cellDuration":
  463. this._appointments.option("items", []);
  464. if (this._readyToRenderAppointments) {
  465. this._updateOption("workSpace", "hoursInterval", value / 60);
  466. this._appointments.option("items", this._getAppointmentsToRepaint())
  467. }
  468. break;
  469. case "tabIndex":
  470. case "focusStateEnabled":
  471. this._updateOption("header", name, value);
  472. this._updateOption("workSpace", name, value);
  473. this._appointments.option(name, value);
  474. this.callBase(args);
  475. break;
  476. case "width":
  477. this._updateOption("header", name, value);
  478. if (this.option("crossScrollingEnabled")) {
  479. this._updateOption("workSpace", "width", value)
  480. }
  481. this.callBase(args);
  482. this._dimensionChanged();
  483. break;
  484. case "height":
  485. this.callBase(args);
  486. this._dimensionChanged();
  487. break;
  488. case "editing":
  489. this._initEditing();
  490. var editing = this._editing;
  491. this._bringEditingModeToAppointments(editing);
  492. this.hideAppointmentTooltip();
  493. this._cleanPopup();
  494. break;
  495. case "showAllDayPanel":
  496. this._postponeResourceLoading().done(function(resources) {
  497. _this2._filterAppointmentsByDate();
  498. _this2._updateOption("workSpace", "allDayExpanded", value);
  499. _this2._updateOption("workSpace", name, value)
  500. });
  501. break;
  502. case "showCurrentTimeIndicator":
  503. case "indicatorTime":
  504. case "indicatorUpdateInterval":
  505. case "shadeUntilCurrentTime":
  506. case "groupByDate":
  507. this._updateOption("workSpace", name, value);
  508. this.repaint();
  509. break;
  510. case "appointmentTooltipTemplate":
  511. case "appointmentPopupTemplate":
  512. case "recurrenceEditMode":
  513. case "remoteFiltering":
  514. case "timeZone":
  515. case "dropDownAppointmentTemplate":
  516. case "appointmentCollectorTemplate":
  517. case "_appointmentTooltipOffset":
  518. case "_appointmentTooltipButtonsPosition":
  519. case "_appointmentTooltipOpenButtonText":
  520. case "_dropDownButtonIcon":
  521. case "_appointmentCountPerCell":
  522. case "_collectorOffset":
  523. case "_appointmentOffset":
  524. this.repaint();
  525. break;
  526. case "dateSerializationFormat":
  527. break;
  528. case "maxAppointmentsPerCell":
  529. break;
  530. case "startDateExpr":
  531. case "endDateExpr":
  532. case "startDateTimeZoneExpr":
  533. case "endDateTimeZoneExpr":
  534. case "textExpr":
  535. case "descriptionExpr":
  536. case "allDayExpr":
  537. case "recurrenceRuleExpr":
  538. case "recurrenceExceptionExpr":
  539. this._updateExpression(name, value);
  540. this._appointmentModel.setDataAccessors(this._combineDataAccessors());
  541. this._initAppointmentTemplate();
  542. this.repaint();
  543. break;
  544. case "adaptivityEnabled":
  545. this._toggleAdaptiveClass();
  546. this.repaint();
  547. break;
  548. default:
  549. this.callBase(args)
  550. }
  551. },
  552. _updateHeader: function() {
  553. var viewCountConfig = this._getViewCountConfig();
  554. this._header.option("intervalCount", viewCountConfig.intervalCount);
  555. this._header.option("displayedDate", this._workSpace._getViewStartByOptions());
  556. this._header.option("min", this._dateOption("min"));
  557. this._header.option("max", this._dateOption("max"));
  558. this._header.option("currentDate", this._dateOption("currentDate"));
  559. this._header.option("firstDayOfWeek", this._getCurrentViewOption("firstDayOfWeek"));
  560. this._header.option("currentView", this._currentView)
  561. },
  562. _dateOption: function(optionName) {
  563. var optionValue = this._getCurrentViewOption(optionName);
  564. return _date_serialization2.default.deserializeDate(optionValue)
  565. },
  566. _getSerializationFormat: function(optionName) {
  567. var value = this._getCurrentViewOption(optionName);
  568. if ("number" === typeof value) {
  569. return "number"
  570. }
  571. if (!_type2.default.isString(value)) {
  572. return
  573. }
  574. return _date_serialization2.default.getDateSerializationFormat(value)
  575. },
  576. _bringEditingModeToAppointments: function(editing) {
  577. var editingConfig = {
  578. allowDelete: editing.allowUpdating && editing.allowDeleting
  579. };
  580. if (!this._isAgenda()) {
  581. editingConfig.allowDrag = editing.allowDragging;
  582. editingConfig.allowResize = editing.allowResizing;
  583. editingConfig.allowAllDayResize = editing.allowResizing && this._supportAllDayResizing()
  584. }
  585. this._appointments.option(editingConfig)
  586. },
  587. _isAgenda: function() {
  588. return "agenda" === this._getAppointmentsRenderingStrategy()
  589. },
  590. _allowDragging: function() {
  591. return this._editing.allowDragging && !this._isAgenda()
  592. },
  593. _allowResizing: function() {
  594. return this._editing.allowResizing && !this._isAgenda()
  595. },
  596. _allowAllDayResizing: function() {
  597. return this._editing.allowResizing && this._supportAllDayResizing()
  598. },
  599. _supportAllDayResizing: function() {
  600. return "day" !== this._getCurrentViewType() || this._currentView.intervalCount > 1
  601. },
  602. _isAllDayExpanded: function(items) {
  603. return this.option("showAllDayPanel") && this._appointmentModel.hasAllDayAppointments(items, this._getCurrentViewOption("startDayHour"), this._getCurrentViewOption("endDayHour"))
  604. },
  605. _getTimezoneOffsetByOption: function(date) {
  606. return this._calculateTimezoneByValue(this.option("timeZone"), date)
  607. },
  608. _calculateTimezoneByValue: function(timezone, date) {
  609. var result = timezone;
  610. if ("string" === typeof timezone) {
  611. date = date || new Date;
  612. var dateUtc = Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes());
  613. result = _uiScheduler30.default.getTimezoneOffsetById(timezone, dateUtc)
  614. }
  615. return result
  616. },
  617. _filterAppointmentsByDate: function() {
  618. var dateRange = this._workSpace.getDateRange();
  619. this._appointmentModel.filterByDate(dateRange[0], dateRange[1], this.option("remoteFiltering"), this.option("dateSerializationFormat"))
  620. },
  621. _loadResources: function() {
  622. var groups = this._getCurrentViewOption("groups");
  623. var result = new Deferred;
  624. this._resourcesManager.loadResources(groups).done(function(resources) {
  625. this._loadedResources = resources;
  626. result.resolve(resources)
  627. }.bind(this));
  628. return result.promise()
  629. },
  630. _dataSourceLoadedCallback: (0, _callbacks2.default)(),
  631. _reloadDataSource: function() {
  632. var result = new Deferred;
  633. if (this._dataSource) {
  634. this._dataSource.load().done(function() {
  635. _ui6.default.hide();
  636. this._fireContentReadyAction(result)
  637. }.bind(this)).fail(function() {
  638. _ui6.default.hide();
  639. result.reject()
  640. });
  641. this._dataSource.isLoading() && _ui6.default.show({
  642. container: this.$element(),
  643. position: {
  644. of: this.$element()
  645. }
  646. })
  647. } else {
  648. this._fireContentReadyAction(result)
  649. }
  650. return result.promise()
  651. },
  652. _fireContentReadyAction: function(result) {
  653. this.callBase();
  654. result && result.resolve()
  655. },
  656. _dimensionChanged: function() {
  657. var filteredItems = this.getFilteredItems();
  658. this._toggleSmallClass();
  659. if (!this._isAgenda() && filteredItems && this._isVisible()) {
  660. this._workSpace._cleanAllowedPositions();
  661. this._workSpace.option("allDayExpanded", this._isAllDayExpanded(filteredItems));
  662. this._workSpace._dimensionChanged();
  663. var appointments = this._layoutManager.createAppointmentsMap(filteredItems);
  664. this._appointments.option("items", appointments)
  665. }
  666. this.hideAppointmentTooltip();
  667. this.resizePopup();
  668. this._updatePopupFullScreenMode()
  669. },
  670. _clean: function() {
  671. this._cleanPopup();
  672. this.callBase()
  673. },
  674. _toggleSmallClass: function() {
  675. var width = this.$element().get(0).getBoundingClientRect().width;
  676. this.$element().toggleClass(WIDGET_SMALL_CLASS, width < WIDGET_SMALL_WIDTH)
  677. },
  678. _toggleAdaptiveClass: function() {
  679. this.$element().toggleClass(WIDGET_ADAPTIVE_CLASS, this.option("adaptivityEnabled"))
  680. },
  681. _visibilityChanged: function(visible) {
  682. visible && this._dimensionChanged()
  683. },
  684. _dataSourceOptions: function() {
  685. return {
  686. paginate: false
  687. }
  688. },
  689. _init: function() {
  690. this._initExpressions({
  691. startDate: this.option("startDateExpr"),
  692. endDate: this.option("endDateExpr"),
  693. startDateTimeZone: this.option("startDateTimeZoneExpr"),
  694. endDateTimeZone: this.option("endDateTimeZoneExpr"),
  695. allDay: this.option("allDayExpr"),
  696. text: this.option("textExpr"),
  697. description: this.option("descriptionExpr"),
  698. recurrenceRule: this.option("recurrenceRuleExpr"),
  699. recurrenceException: this.option("recurrenceExceptionExpr")
  700. });
  701. this.callBase();
  702. this._initDataSource();
  703. this._loadedResources = [];
  704. this._proxiedCustomizeStoreLoadOptionsHandler = this._customizeStoreLoadOptionsHandler.bind(this);
  705. this._customizeStoreLoadOptions();
  706. this.$element().addClass(WIDGET_CLASS).toggleClass(WIDGET_WIN_NO_TOUCH_CLASS, !!(_browser2.default.msie && _support.touch));
  707. this._initEditing();
  708. this._resourcesManager = new _uiScheduler24.default(this.option("resources"));
  709. var combinedDataAccessors = this._combineDataAccessors();
  710. this._appointmentModel = new _uiScheduler26.default(this._dataSource, combinedDataAccessors, this.getAppointmentDurationInMinutes());
  711. this._initActions();
  712. this._compactAppointmentsHelper = new _compactAppointmentsHelper.CompactAppointmentsHelper(this);
  713. this._subscribes = _uiScheduler2.default
  714. },
  715. _initTemplates: function() {
  716. this.callBase();
  717. this._initAppointmentTemplate();
  718. this._defaultTemplates.appointmentTooltip = new _empty_template2.default(this);
  719. this._defaultTemplates.appointmentPopup = new _empty_template2.default(this);
  720. this._defaultTemplates.dropDownAppointment = new _empty_template2.default(this)
  721. },
  722. _initAppointmentTemplate: function() {
  723. var that = this;
  724. this._defaultTemplates.item = new _bindable_template2.default(function($container, data, model) {
  725. var appointmentsInst = that.getAppointmentsInstance();
  726. appointmentsInst._renderAppointmentTemplate.call(appointmentsInst, $container, data, model)
  727. }, ["html", "text", "startDate", "endDate", "allDay", "description", "recurrenceRule", "recurrenceException", "startDateTimeZone", "endDateTimeZone"], this.option("integrationOptions.watchMethod"), {
  728. text: this._dataAccessors.getter.text,
  729. startDate: this._dataAccessors.getter.startDate,
  730. endDate: this._dataAccessors.getter.endDate,
  731. startDateTimeZone: this._dataAccessors.getter.startDateTimeZone,
  732. endDateTimeZone: this._dataAccessors.getter.endDateTimeZone,
  733. allDay: this._dataAccessors.getter.allDay,
  734. recurrenceRule: this._dataAccessors.getter.recurrenceRule
  735. })
  736. },
  737. _combineDataAccessors: function() {
  738. var resourcesDataAccessors = this._resourcesManager._dataAccessors;
  739. var result = (0, _extend.extend)(true, {}, this._dataAccessors);
  740. (0, _iterator.each)(resourcesDataAccessors, function(type, accessor) {
  741. result[type].resources = accessor
  742. }.bind(this));
  743. return result
  744. },
  745. _renderContent: function() {
  746. this._renderContentImpl()
  747. },
  748. _dataSourceChangedHandler: function(result) {
  749. if (this._readyToRenderAppointments) {
  750. this._workSpaceRecalculation.done(function() {
  751. this._filteredItems = this.fire("prerenderFilter");
  752. this._workSpace.option("allDayExpanded", this._isAllDayExpanded(this._filteredItems));
  753. if (this._isAgenda()) {
  754. this.getRenderingStrategyInstance().calculateRows(this._filteredItems, 7, this.option("currentDate"), true)
  755. }
  756. if (this._filteredItems.length && this._isVisible()) {
  757. this._appointments.option("items", this._getAppointmentsToRepaint());
  758. this._appointmentModel.cleanModelState()
  759. } else {
  760. this._appointments.option("items", [])
  761. }
  762. if (this._isAgenda()) {
  763. this._workSpace._renderView();
  764. this._dataSourceLoadedCallback.fireWith(this, [result])
  765. }
  766. }.bind(this))
  767. }
  768. },
  769. _getAppointmentsToRepaint: function() {
  770. var appointments = this._layoutManager.createAppointmentsMap(this._filteredItems);
  771. return this._layoutManager.getRepaintedAppointments(appointments, this.getAppointmentsInstance().option("items"))
  772. },
  773. _initExpressions: function(fields) {
  774. var dataCoreUtils = require("../../core/utils/data");
  775. var isDateField = function(field) {
  776. return "startDate" === field || "endDate" === field
  777. };
  778. if (!this._dataAccessors) {
  779. this._dataAccessors = {
  780. getter: {},
  781. setter: {},
  782. expr: {}
  783. }
  784. }(0, _iterator.each)(fields, function(name, expr) {
  785. if (expr) {
  786. var getter = dataCoreUtils.compileGetter(expr);
  787. var setter = dataCoreUtils.compileSetter(expr);
  788. var dateGetter;
  789. var dateSetter;
  790. if (isDateField(name)) {
  791. var that = this;
  792. dateGetter = function() {
  793. var value = getter.apply(this, arguments);
  794. if ((0, _config2.default)().forceIsoDateParsing) {
  795. if (!that.option("dateSerializationFormat")) {
  796. var format = _date_serialization2.default.getDateSerializationFormat(value);
  797. if (format) {
  798. that.option("dateSerializationFormat", format)
  799. }
  800. }
  801. value = _date_serialization2.default.deserializeDate(value)
  802. }
  803. return value
  804. };
  805. dateSetter = function(object, value) {
  806. if ((0, _config2.default)().forceIsoDateParsing || that.option("dateSerializationFormat")) {
  807. value = _date_serialization2.default.serializeDate(value, that.option("dateSerializationFormat"))
  808. }
  809. setter.call(this, object, value)
  810. }
  811. }
  812. this._dataAccessors.getter[name] = dateGetter || getter;
  813. this._dataAccessors.setter[name] = dateSetter || setter;
  814. this._dataAccessors.expr[name + "Expr"] = expr
  815. } else {
  816. delete this._dataAccessors.getter[name];
  817. delete this._dataAccessors.setter[name];
  818. delete this._dataAccessors.expr[name + "Expr"]
  819. }
  820. }.bind(this))
  821. },
  822. _updateExpression: function(name, value) {
  823. var exprObj = {};
  824. exprObj[name.replace("Expr", "")] = value;
  825. this._initExpressions(exprObj)
  826. },
  827. _initEditing: function() {
  828. var editing = this.option("editing");
  829. this._editing = {
  830. allowAdding: !!editing,
  831. allowUpdating: !!editing,
  832. allowDeleting: !!editing,
  833. allowResizing: !!editing,
  834. allowDragging: !!editing
  835. };
  836. if (_type2.default.isObject(editing)) {
  837. this._editing = (0, _extend.extend)(this._editing, editing)
  838. }
  839. this._editing.allowDragging = this._editing.allowDragging && this._editing.allowUpdating;
  840. this._editing.allowResizing = this._editing.allowResizing && this._editing.allowUpdating;
  841. this.$element().toggleClass(WIDGET_READONLY_CLASS, this._isReadOnly())
  842. },
  843. _isReadOnly: function() {
  844. var result = true;
  845. var editing = this._editing;
  846. for (var prop in editing) {
  847. if (Object.prototype.hasOwnProperty.call(editing, prop)) {
  848. result = result && !editing[prop]
  849. }
  850. }
  851. return result
  852. },
  853. _customizeStoreLoadOptions: function() {
  854. this._dataSource && this._dataSource.on("customizeStoreLoadOptions", this._proxiedCustomizeStoreLoadOptionsHandler)
  855. },
  856. _dispose: function() {
  857. this._appointmentTooltip && this._appointmentTooltip.dispose();
  858. this.hideAppointmentPopup();
  859. this.hideAppointmentTooltip();
  860. this._cleanAsyncTemplatesTimer();
  861. this._dataSource && this._dataSource.off("customizeStoreLoadOptions", this._proxiedCustomizeStoreLoadOptionsHandler);
  862. this.callBase()
  863. },
  864. _customizeStoreLoadOptionsHandler: function(options) {
  865. options.storeLoadOptions.dxScheduler = {
  866. startDate: this.getStartViewDate(),
  867. endDate: this.getEndViewDate(),
  868. resources: this.option("resources")
  869. }
  870. },
  871. _initActions: function() {
  872. this._actions = {
  873. onAppointmentAdding: this._createActionByOption("onAppointmentAdding"),
  874. onAppointmentAdded: this._createActionByOption("onAppointmentAdded"),
  875. onAppointmentUpdating: this._createActionByOption("onAppointmentUpdating"),
  876. onAppointmentUpdated: this._createActionByOption("onAppointmentUpdated"),
  877. onAppointmentDeleting: this._createActionByOption("onAppointmentDeleting"),
  878. onAppointmentDeleted: this._createActionByOption("onAppointmentDeleted"),
  879. onAppointmentFormOpening: this._createActionByOption("onAppointmentFormOpening")
  880. }
  881. },
  882. _getAppointmentRenderedAction: function() {
  883. return this._createActionByOption("onAppointmentRendered", {
  884. excludeValidators: ["disabled", "readOnly"]
  885. })
  886. },
  887. _renderFocusTarget: _common.noop,
  888. _initMarkup: function() {
  889. this.callBase();
  890. this._processCurrentView();
  891. this._renderHeader();
  892. this._layoutManager = new _uiSchedulerAppointments2.default(this, this._getAppointmentsRenderingStrategy());
  893. this._appointments = this._createComponent("<div>", _uiScheduler28.default, this._appointmentsConfig());
  894. this._appointments.option("itemTemplate", this._getAppointmentTemplate("appointmentTemplate"));
  895. this._appointmentTooltip = this.option("adaptivityEnabled") ? new _mobileTooltipStrategy.MobileTooltipStrategy(this) : new _desktopTooltipStrategy.DesktopTooltipStrategy(this);
  896. if (this._isLoaded()) {
  897. this._initMarkupCore(this._loadedResources);
  898. this._dataSourceChangedHandler(this._dataSource.items());
  899. this._fireContentReadyAction()
  900. } else {
  901. this._loadResources().done(function(resources) {
  902. this._initMarkupCore(resources);
  903. this._reloadDataSource()
  904. }.bind(this))
  905. }
  906. },
  907. _initMarkupCore: function(resources) {
  908. var _this3 = this;
  909. this._readyToRenderAppointments = _window2.default.hasWindow();
  910. this._workSpace && this._cleanWorkspace();
  911. this._renderWorkSpace(resources);
  912. this._appointments.option({
  913. fixedContainer: this._workSpace.getFixedContainer(),
  914. allDayContainer: this._workSpace.getAllDayContainer()
  915. });
  916. this._waitAsyncTemplates(function() {
  917. _this3._workSpaceRecalculation && _this3._workSpaceRecalculation.resolve()
  918. });
  919. this._filterAppointmentsByDate()
  920. },
  921. _isLoaded: function() {
  922. return this._isResourcesLoaded() && this._isDataSourceLoaded()
  923. },
  924. _isResourcesLoaded: function() {
  925. return _type2.default.isDefined(this._loadedResources)
  926. },
  927. _isDataSourceLoaded: function() {
  928. return this._dataSource && this._dataSource.isLoaded()
  929. },
  930. _render: function() {
  931. this._toggleSmallClass();
  932. this._toggleAdaptiveClass();
  933. this.callBase()
  934. },
  935. _renderHeader: function() {
  936. var $header = (0, _renderer2.default)("<div>").appendTo(this.$element());
  937. this._header = this._createComponent($header, _uiScheduler4.default, this._headerConfig())
  938. },
  939. _headerConfig: function() {
  940. var currentViewOptions = this._getCurrentViewOptions();
  941. var countConfig = this._getViewCountConfig();
  942. var result = (0, _extend.extend)({
  943. firstDayOfWeek: this.option("firstDayOfWeek"),
  944. currentView: this._currentView,
  945. tabIndex: this.option("tabIndex"),
  946. focusStateEnabled: this.option("focusStateEnabled"),
  947. width: this.option("width"),
  948. rtlEnabled: this.option("rtlEnabled"),
  949. useDropDownViewSwitcher: this.option("useDropDownViewSwitcher"),
  950. _dropDownButtonIcon: this.option("_dropDownButtonIcon"),
  951. customizeDateNavigatorText: this.option("customizeDateNavigatorText")
  952. }, currentViewOptions);
  953. result.observer = this;
  954. result.intervalCount = countConfig.intervalCount;
  955. result.views = this.option("views");
  956. result.min = new Date(this._dateOption("min"));
  957. result.max = new Date(this._dateOption("max"));
  958. result.currentDate = _date2.default.trimTime(new Date(this._dateOption("currentDate")));
  959. return result
  960. },
  961. _appointmentsConfig: function() {
  962. var that = this;
  963. var config = {
  964. observer: this,
  965. onItemRendered: this._getAppointmentRenderedAction(),
  966. onItemClick: this._createActionByOption("onAppointmentClick"),
  967. onItemContextMenu: this._createActionByOption("onAppointmentContextMenu"),
  968. onAppointmentDblClick: this._createActionByOption("onAppointmentDblClick"),
  969. tabIndex: this.option("tabIndex"),
  970. focusStateEnabled: this.option("focusStateEnabled"),
  971. allowDrag: this._allowDragging(),
  972. allowDelete: this._editing.allowUpdating && this._editing.allowDeleting,
  973. allowResize: this._allowResizing(),
  974. allowAllDayResize: this._allowAllDayResizing(),
  975. rtlEnabled: this.option("rtlEnabled"),
  976. onContentReady: function() {
  977. that._workSpace && that._workSpace.option("allDayExpanded", that._isAllDayExpanded(that.getFilteredItems()));
  978. }
  979. };
  980. return config
  981. },
  982. getCollectorOffset: function() {
  983. if (this._workSpace.needApplyCollectorOffset() && !this.option("adaptivityEnabled")) {
  984. return this.option("_collectorOffset")
  985. } else {
  986. return 0
  987. }
  988. },
  989. getAppointmentDurationInMinutes: function() {
  990. return this._getCurrentViewOption("cellDuration")
  991. },
  992. _processCurrentView: function() {
  993. var views = this.option("views");
  994. var currentView = this.option("currentView");
  995. var that = this;
  996. this._currentView = currentView;
  997. (0, _iterator.each)(views, function(_, view) {
  998. var isViewIsObject = _type2.default.isObject(view);
  999. var viewName = isViewIsObject ? view.name : view;
  1000. var viewType = view.type;
  1001. if (currentView === viewName || currentView === viewType) {
  1002. that._currentView = view;
  1003. return false
  1004. }
  1005. })
  1006. },
  1007. _getCurrentViewType: function() {
  1008. return this._currentView.type || this._currentView
  1009. },
  1010. _getAppointmentsRenderingStrategy: function() {
  1011. return VIEWS_CONFIG[this._getCurrentViewType()].renderingStrategy
  1012. },
  1013. _renderWorkSpace: function(groups) {
  1014. this._readyToRenderAppointments && this._toggleSmallClass();
  1015. var $workSpace = (0, _renderer2.default)("<div>").appendTo(this.$element());
  1016. var countConfig = this._getViewCountConfig();
  1017. this._workSpace = this._createComponent($workSpace, VIEWS_CONFIG[this._getCurrentViewType()].workSpace, this._workSpaceConfig(groups, countConfig));
  1018. this._workSpace.getWorkArea().append(this._appointments.$element());
  1019. this._recalculateWorkspace();
  1020. countConfig.startDate && this._header && this._header.option("currentDate", this._workSpace._getHeaderDate());
  1021. this._appointments.option("_collectorOffset", this.getCollectorOffset())
  1022. },
  1023. _getViewCountConfig: function() {
  1024. var currentView = this.option("currentView");
  1025. var view = this._getViewByName(currentView);
  1026. var viewCount = view && view.intervalCount || 1;
  1027. var startDate = view && view.startDate || null;
  1028. return {
  1029. intervalCount: viewCount,
  1030. startDate: startDate
  1031. }
  1032. },
  1033. _getViewByName: function(name) {
  1034. var views = this.option("views");
  1035. for (var i = 0; i < views.length; i++) {
  1036. if (views[i].name === name || views[i].type === name || views[i] === name) {
  1037. return views[i]
  1038. }
  1039. }
  1040. },
  1041. _recalculateWorkspace: function() {
  1042. var _this4 = this;
  1043. this._workSpaceRecalculation = new Deferred;
  1044. this._waitAsyncTemplates(function() {
  1045. _dom2.default.triggerResizeEvent(_this4._workSpace.$element());
  1046. _this4._workSpace._refreshDateTimeIndication()
  1047. })
  1048. },
  1049. _workSpaceConfig: function(groups, countConfig) {
  1050. var _this5 = this;
  1051. var currentViewOptions = this._getCurrentViewOptions();
  1052. var result = (0, _extend.extend)({
  1053. noDataText: this.option("noDataText"),
  1054. firstDayOfWeek: this.option("firstDayOfWeek"),
  1055. startDayHour: this.option("startDayHour"),
  1056. endDayHour: this.option("endDayHour"),
  1057. tabIndex: this.option("tabIndex"),
  1058. accessKey: this.option("accessKey"),
  1059. focusStateEnabled: this.option("focusStateEnabled"),
  1060. cellDuration: this.option("cellDuration"),
  1061. showAllDayPanel: this.option("showAllDayPanel"),
  1062. showCurrentTimeIndicator: this.option("showCurrentTimeIndicator"),
  1063. indicatorTime: this.option("indicatorTime"),
  1064. indicatorUpdateInterval: this.option("indicatorUpdateInterval"),
  1065. shadeUntilCurrentTime: this.option("shadeUntilCurrentTime"),
  1066. allDayExpanded: this._appointments.option("items"),
  1067. crossScrollingEnabled: this.option("crossScrollingEnabled"),
  1068. dataCellTemplate: this.option("dataCellTemplate"),
  1069. timeCellTemplate: this.option("timeCellTemplate"),
  1070. resourceCellTemplate: this.option("resourceCellTemplate"),
  1071. dateCellTemplate: this.option("dateCellTemplate"),
  1072. allowMultipleCellSelection: this.option("allowMultipleCellSelection"),
  1073. selectedCellData: this.option("selectedCellData"),
  1074. onSelectionChanged: function(args) {
  1075. _this5.option("selectedCellData", args.selectedCellData)
  1076. },
  1077. groupByDate: this._getCurrentViewOption("groupByDate")
  1078. }, currentViewOptions);
  1079. result.observer = this;
  1080. result.intervalCount = countConfig.intervalCount;
  1081. result.startDate = countConfig.startDate;
  1082. result.groups = groups;
  1083. result.onCellClick = this._createActionByOption("onCellClick");
  1084. result.onCellContextMenu = this._createActionByOption("onCellContextMenu");
  1085. result.min = new Date(this._dateOption("min"));
  1086. result.max = new Date(this._dateOption("max"));
  1087. result.currentDate = _date2.default.trimTime(new Date(this._dateOption("currentDate")));
  1088. result.hoursInterval = result.cellDuration / 60;
  1089. result.allDayExpanded = this._isAllDayExpanded(this.getFilteredItems());
  1090. result.dataCellTemplate = result.dataCellTemplate ? this._getTemplate(result.dataCellTemplate) : null;
  1091. result.timeCellTemplate = result.timeCellTemplate ? this._getTemplate(result.timeCellTemplate) : null;
  1092. result.resourceCellTemplate = result.resourceCellTemplate ? this._getTemplate(result.resourceCellTemplate) : null;
  1093. result.dateCellTemplate = result.dateCellTemplate ? this._getTemplate(result.dateCellTemplate) : null;
  1094. return result
  1095. },
  1096. _getCurrentViewOptions: function() {
  1097. return this._currentView
  1098. },
  1099. _getCurrentViewOption: function(optionName) {
  1100. var currentViewOptions = this._getCurrentViewOptions();
  1101. if (currentViewOptions && void 0 !== currentViewOptions[optionName]) {
  1102. return currentViewOptions[optionName]
  1103. }
  1104. return this.option(optionName)
  1105. },
  1106. _getAppointmentTemplate: function(optionName) {
  1107. var currentViewOptions = this._getCurrentViewOptions();
  1108. if (currentViewOptions && currentViewOptions[optionName]) {
  1109. return this._getTemplate(currentViewOptions[optionName])
  1110. }
  1111. return this._getTemplateByOption(optionName)
  1112. },
  1113. _updateOption: function(viewName, optionName, value) {
  1114. var currentViewOptions = this._getCurrentViewOptions();
  1115. if (!currentViewOptions || !_type2.default.isDefined(currentViewOptions[optionName])) {
  1116. this["_" + viewName].option(optionName, value)
  1117. }
  1118. },
  1119. _refreshWorkSpace: function(groups) {
  1120. var _this6 = this;
  1121. this._cleanWorkspace();
  1122. delete this._workSpace;
  1123. this._renderWorkSpace(groups);
  1124. if (this._readyToRenderAppointments) {
  1125. this._appointments.option({
  1126. fixedContainer: this._workSpace.getFixedContainer(),
  1127. allDayContainer: this._workSpace.getAllDayContainer()
  1128. });
  1129. this._waitAsyncTemplates(function() {
  1130. _this6._workSpaceRecalculation.resolve()
  1131. })
  1132. }
  1133. },
  1134. _cleanWorkspace: function() {
  1135. this._appointments.$element().detach();
  1136. this._workSpace._dispose();
  1137. this._workSpace.$element().remove();
  1138. this.option("selectedCellData", [])
  1139. },
  1140. getWorkSpaceScrollable: function() {
  1141. return this._workSpace.getScrollable()
  1142. },
  1143. getWorkSpaceScrollableScrollTop: function(allDay) {
  1144. return this._workSpace.getGroupedScrollableScrollTop(allDay)
  1145. },
  1146. getWorkSpaceScrollableScrollLeft: function() {
  1147. return this._workSpace.getScrollableScrollLeft()
  1148. },
  1149. getWorkSpaceScrollableContainer: function() {
  1150. return this._workSpace.getScrollableContainer()
  1151. },
  1152. getWorkSpaceAllDayHeight: function() {
  1153. return this._workSpace.getAllDayHeight()
  1154. },
  1155. getWorkSpaceAllDayOffset: function() {
  1156. return this._workSpace.getAllDayOffset()
  1157. },
  1158. getWorkSpaceHeaderPanelHeight: function() {
  1159. return this._workSpace.getHeaderPanelHeight()
  1160. },
  1161. getWorkSpaceDateTableOffset: function() {
  1162. return !this.option("crossScrollingEnabled") || this.option("rtlEnabled") ? this._workSpace.getWorkSpaceLeftOffset() : 0
  1163. },
  1164. getWorkSpace: function() {
  1165. return this._workSpace
  1166. },
  1167. getAppointmentModel: function() {
  1168. return this._appointmentModel
  1169. },
  1170. getHeader: function() {
  1171. return this._header
  1172. },
  1173. getMaxAppointmentsPerCell: function() {
  1174. return this._getCurrentViewOption("maxAppointmentsPerCell")
  1175. },
  1176. _createPopup: function(appointmentData, processTimeZone) {
  1177. this._$popup = (0, _renderer2.default)("<div>").addClass(APPOINTMENT_POPUP_CLASS).appendTo(this.$element());
  1178. this._initDynamicPopupTemplate(appointmentData, processTimeZone);
  1179. this._popup = this._createComponent(this._$popup, _popup2.default, this._popupConfig(appointmentData))
  1180. },
  1181. _popupContent: function(appointmentData, processTimeZone) {
  1182. var $popupContent = this._popup.$content();
  1183. var $form = (0, _renderer2.default)("<div>").appendTo($popupContent);
  1184. this._createOrUpdateForm(appointmentData, processTimeZone, $form);
  1185. return $popupContent
  1186. },
  1187. _createAppointmentForm: function(formData, $content) {
  1188. var allDay = this.fire("getField", "allDay", formData);
  1189. var resources = this.option("resources");
  1190. _uiScheduler32.default.prepareAppointmentFormEditors(allDay, {
  1191. textExpr: this._dataAccessors.expr.textExpr,
  1192. allDayExpr: this._dataAccessors.expr.allDayExpr,
  1193. startDateExpr: this._dataAccessors.expr.startDateExpr,
  1194. endDateExpr: this._dataAccessors.expr.endDateExpr,
  1195. descriptionExpr: this._dataAccessors.expr.descriptionExpr,
  1196. recurrenceRuleExpr: this._dataAccessors.expr.recurrenceRuleExpr,
  1197. startDateTimeZoneExpr: this._dataAccessors.expr.startDateTimeZoneExpr,
  1198. endDateTimeZoneExpr: this._dataAccessors.expr.endDateTimeZoneExpr
  1199. }, this);
  1200. if (resources && resources.length) {
  1201. this._resourcesManager.setResources(this.option("resources"));
  1202. _uiScheduler32.default.concatResources(this._resourcesManager.getEditors())
  1203. }
  1204. this._appointmentForm = _uiScheduler32.default.create(this._createComponent.bind(this), $content, this._editAppointmentData ? !this._editing.allowUpdating : false, formData)
  1205. },
  1206. _createOrUpdateForm: function(appointmentData, processTimeZone, $content) {
  1207. var allDay = this.fire("getField", "allDay", appointmentData);
  1208. var startDate = this.fire("getField", "startDate", appointmentData);
  1209. var endDate = this.fire("getField", "endDate", appointmentData);
  1210. (0, _iterator.each)(this._resourcesManager.getResourcesFromItem(appointmentData, true) || {}, function(resourceName, resourceValue) {
  1211. appointmentData[resourceName] = resourceValue
  1212. });
  1213. var formData = (0, _extend.extend)(true, {}, appointmentData);
  1214. if (processTimeZone) {
  1215. startDate = this.fire("convertDateByTimezone", startDate);
  1216. endDate = this.fire("convertDateByTimezone", endDate);
  1217. this.fire("setField", "startDate", formData, startDate);
  1218. this.fire("setField", "endDate", formData, endDate)
  1219. }
  1220. if (this._appointmentForm) {
  1221. var startDateExpr = this._dataAccessors.expr.startDateExpr;
  1222. var endDateExpr = this._dataAccessors.expr.endDateExpr;
  1223. formData.recurrenceRule = formData.recurrenceRule || null;
  1224. _uiScheduler32.default.updateFormData(this._appointmentForm, formData);
  1225. this._appointmentForm.option("readOnly", this._editAppointmentData ? !this._editing.allowUpdating : false);
  1226. _uiScheduler32.default.checkEditorsType(this._appointmentForm, startDateExpr, endDateExpr, allDay)
  1227. } else {
  1228. this._createAppointmentForm(formData, $content)
  1229. }
  1230. var recurrenceRuleExpr = this._dataAccessors.expr.recurrenceRuleExpr;
  1231. var recurrentEditorItem = recurrenceRuleExpr ? this._appointmentForm.itemOption(recurrenceRuleExpr) : null;
  1232. if (recurrentEditorItem) {
  1233. var options = recurrentEditorItem.editorOptions || {};
  1234. options.startDate = startDate;
  1235. this._appointmentForm.itemOption(recurrenceRuleExpr, "editorOptions", options)
  1236. }
  1237. this._actions.onAppointmentFormOpening({
  1238. form: this._appointmentForm,
  1239. appointmentData: appointmentData
  1240. })
  1241. },
  1242. _initDynamicPopupTemplate: function(appointmentData, processTimeZone) {
  1243. var that = this;
  1244. this._defaultTemplates.appointmentPopup = new _function_template2.default(function(options) {
  1245. var $popupContent = that._popupContent(appointmentData, processTimeZone);
  1246. (0, _renderer2.default)(options.container).append($popupContent);
  1247. return (0, _renderer2.default)(options.container)
  1248. })
  1249. },
  1250. _isPopupFullScreenNeeded: function() {
  1251. if (_window2.default.hasWindow()) {
  1252. var window = _window2.default.getWindow();
  1253. return (0, _renderer2.default)(window).width() < APPOINTMENT_POPUP_FULLSCREEN_WINDOW_WIDTH
  1254. }
  1255. return false
  1256. },
  1257. _updatePopupFullScreenMode: function() {
  1258. if (this._popup && this._popup.option("visible")) {
  1259. var isFullScreen = this._isPopupFullScreenNeeded();
  1260. this._popup.option({
  1261. maxWidth: isFullScreen ? "100%" : APPOINTMENT_POPUP_WIDTH,
  1262. fullScreen: isFullScreen
  1263. })
  1264. }
  1265. },
  1266. _popupConfig: function(appointmentData) {
  1267. var _this7 = this;
  1268. var template = this._getTemplateByOption("appointmentPopupTemplate");
  1269. return {
  1270. height: "auto",
  1271. maxHeight: "100%",
  1272. onHiding: function() {
  1273. return _this7.focus()
  1274. },
  1275. contentTemplate: new _function_template2.default(function(options) {
  1276. return template.render({
  1277. model: appointmentData,
  1278. container: options.container
  1279. })
  1280. }),
  1281. onShowing: function() {
  1282. return _this7._updatePopupFullScreenMode()
  1283. },
  1284. defaultOptionsRules: [{
  1285. device: function() {
  1286. return _devices2.default.current().android
  1287. },
  1288. options: {
  1289. showTitle: false
  1290. }
  1291. }]
  1292. }
  1293. },
  1294. _getPopupToolbarItems: function() {
  1295. var isIOs = "ios" === _devices2.default.current().platform;
  1296. return [{
  1297. shortcut: "done",
  1298. location: TOOLBAR_ITEM_AFTER_LOCATION,
  1299. onClick: this._doneButtonClickHandler.bind(this)
  1300. }, {
  1301. shortcut: "cancel",
  1302. location: isIOs ? TOOLBAR_ITEM_BEFORE_LOCATION : TOOLBAR_ITEM_AFTER_LOCATION
  1303. }]
  1304. },
  1305. _cleanPopup: function() {
  1306. if (this._$popup) {
  1307. this._popup.$element().remove();
  1308. delete this._$popup;
  1309. delete this._popup;
  1310. delete this._appointmentForm
  1311. }
  1312. },
  1313. _doneButtonClickHandler: function(args) {
  1314. args.cancel = true;
  1315. this._saveChanges(true);
  1316. if (this._lastEditData) {
  1317. var startDate = this.fire("getField", "startDate", this._lastEditData);
  1318. this._workSpace.updateScrollPosition(startDate);
  1319. delete this._lastEditData
  1320. }
  1321. },
  1322. _saveChanges: function(disableButton) {
  1323. var validation = this._appointmentForm.validate();
  1324. if (validation && !validation.isValid) {
  1325. return false
  1326. }
  1327. disableButton && this._disableDoneButton();
  1328. var formData = _object2.default.deepExtendArraySafe({}, this._getFormData(), true);
  1329. var oldData = this._editAppointmentData;
  1330. var recData = this._updatedRecAppointment;
  1331. function convert(obj, dateFieldName) {
  1332. var date = new Date(this.fire("getField", dateFieldName, obj));
  1333. var tzDiff = this._getTimezoneOffsetByOption() * toMs("hour") + this.fire("getClientTimezoneOffset", date);
  1334. return new Date(date.getTime() + tzDiff)
  1335. }
  1336. if (oldData) {
  1337. this._convertDatesByTimezoneBack(false, formData)
  1338. }
  1339. if (oldData && !recData) {
  1340. this.updateAppointment(oldData, formData)
  1341. } else {
  1342. if (recData) {
  1343. this.updateAppointment(oldData, recData);
  1344. delete this._updatedRecAppointment;
  1345. if ("number" === typeof this._getTimezoneOffsetByOption()) {
  1346. this.fire("setField", "startDate", formData, convert.call(this, formData, "startDate"));
  1347. this.fire("setField", "endDate", formData, convert.call(this, formData, "endDate"))
  1348. }
  1349. }
  1350. this.addAppointment(formData)
  1351. }
  1352. this._enableDoneButton();
  1353. this._lastEditData = formData;
  1354. return true
  1355. },
  1356. _getFormData: function() {
  1357. var formData = this._appointmentForm.option("formData");
  1358. var startDate = this.fire("getField", "startDate", formData);
  1359. var endDate = this.fire("getField", "endDate", formData);
  1360. this.fire("setField", "startDate", formData, startDate);
  1361. this.fire("setField", "endDate", formData, endDate);
  1362. return formData
  1363. },
  1364. _convertDatesByTimezoneBack: function(applyAppointmentTimezone, sourceAppointmentData, targetAppointmentData) {
  1365. targetAppointmentData = targetAppointmentData || sourceAppointmentData;
  1366. var processedStartDate = this.fire("convertDateByTimezoneBack", this.fire("getField", "startDate", sourceAppointmentData), applyAppointmentTimezone && this.fire("getField", "startDateTimeZone", sourceAppointmentData));
  1367. var processedEndDate = this.fire("convertDateByTimezoneBack", this.fire("getField", "endDate", sourceAppointmentData), applyAppointmentTimezone && this.fire("getField", "endDateTimeZone", sourceAppointmentData));
  1368. this.fire("setField", "startDate", targetAppointmentData, processedStartDate);
  1369. this.fire("setField", "endDate", targetAppointmentData, processedEndDate)
  1370. },
  1371. _disableDoneButton: function() {
  1372. var toolbarItems = this._popup.option("toolbarItems");
  1373. toolbarItems[0].options = (0, _extend.extend)(toolbarItems[0].options, {
  1374. disabled: true
  1375. });
  1376. this._popup.option("toolbarItems", toolbarItems)
  1377. },
  1378. _enableDoneButton: function() {
  1379. var toolbarItems = this._popup.option("toolbarItems");
  1380. toolbarItems[0].options = (0, _extend.extend)(toolbarItems[0].options, {
  1381. disabled: false
  1382. });
  1383. this._popup.option("toolbarItems", toolbarItems)
  1384. },
  1385. _checkRecurringAppointment: function(targetAppointment, singleAppointment, exceptionDate, callback, isDeleted, isPopupEditing) {
  1386. delete this._updatedRecAppointment;
  1387. var recurrenceRule = this.fire("getField", "recurrenceRule", targetAppointment);
  1388. if (!_utils2.default.getRecurrenceRule(recurrenceRule).isValid || !this._editing.allowUpdating) {
  1389. callback();
  1390. return
  1391. }
  1392. var editMode = this.option("recurrenceEditMode");
  1393. switch (editMode) {
  1394. case "series":
  1395. callback();
  1396. break;
  1397. case "occurrence":
  1398. this._singleAppointmentChangesHandler(targetAppointment, singleAppointment, exceptionDate, isDeleted, isPopupEditing);
  1399. break;
  1400. default:
  1401. this._showRecurrenceChangeConfirm(isDeleted).done(function(result) {
  1402. result && callback();
  1403. !result && this._singleAppointmentChangesHandler(targetAppointment, singleAppointment, exceptionDate, isDeleted, isPopupEditing)
  1404. }.bind(this)).fail(function() {
  1405. this._appointments.moveAppointmentBack()
  1406. }.bind(this))
  1407. }
  1408. },
  1409. _singleAppointmentChangesHandler: function(targetAppointment, singleAppointment, exceptionDate, isDeleted, isPopupEditing) {
  1410. exceptionDate = new Date(exceptionDate);
  1411. function processAppointmentDates(appointment, commonTimezoneOffset) {
  1412. var startDate = this.fire("getField", "startDate", appointment);
  1413. var processedStartDate = this.fire("convertDateByTimezoneBack", startDate, this.fire("getField", "startDateTimeZone", appointment));
  1414. var endDate = this.fire("getField", "endDate", appointment);
  1415. var processedEndDate = this.fire("convertDateByTimezoneBack", endDate, this.fire("getField", "endDateTimeZone", appointment));
  1416. if ("number" === typeof commonTimezoneOffset && !isNaN(commonTimezoneOffset)) {
  1417. var startDateClientTzOffset = -(this._subscribes.getClientTimezoneOffset(startDate) / toMs("hour"));
  1418. var endDateClientTzOffset = -(this._subscribes.getClientTimezoneOffset(endDate) / toMs("hour"));
  1419. var processedStartDateInUTC = processedStartDate.getTime() - startDateClientTzOffset * toMs("hour");
  1420. var processedEndDateInUTC = processedEndDate.getTime() - endDateClientTzOffset * toMs("hour");
  1421. processedStartDate = new Date(processedStartDateInUTC + commonTimezoneOffset * toMs("hour"));
  1422. processedEndDate = new Date(processedEndDateInUTC + commonTimezoneOffset * toMs("hour"))
  1423. }
  1424. this.fire("setField", "startDate", appointment, processedStartDate);
  1425. this.fire("setField", "endDate", appointment, processedEndDate)
  1426. }
  1427. this.fire("setField", "recurrenceRule", singleAppointment, "");
  1428. this.fire("setField", "recurrenceException", singleAppointment, "");
  1429. if (!isDeleted && !isPopupEditing) {
  1430. processAppointmentDates.call(this, singleAppointment, this._getTimezoneOffsetByOption());
  1431. this.addAppointment(singleAppointment)
  1432. }
  1433. var recurrenceException = this._makeDateAsRecurrenceException(exceptionDate, targetAppointment);
  1434. var updatedAppointment = (0, _extend.extend)({}, targetAppointment);
  1435. this.fire("setField", "recurrenceException", updatedAppointment, recurrenceException);
  1436. if (isPopupEditing) {
  1437. this._updatedRecAppointment = updatedAppointment;
  1438. processAppointmentDates.call(this, singleAppointment);
  1439. this._showAppointmentPopup(singleAppointment, true, true);
  1440. this._editAppointmentData = targetAppointment
  1441. } else {
  1442. this._updateAppointment(targetAppointment, updatedAppointment, function() {
  1443. this._appointments.moveAppointmentBack()
  1444. })
  1445. }
  1446. },
  1447. _makeDateAsRecurrenceException: function(exceptionDate, targetAppointment) {
  1448. var startDate = this._getStartDate(targetAppointment, true);
  1449. var startDateTimeZone = this.fire("getField", "startDateTimeZone", targetAppointment);
  1450. var exceptionByDate = this._getRecurrenceExceptionDate(exceptionDate, startDate, startDateTimeZone);
  1451. var recurrenceException = this.fire("getField", "recurrenceException", targetAppointment);
  1452. return recurrenceException ? recurrenceException + "," + exceptionByDate : exceptionByDate
  1453. },
  1454. _getRecurrenceExceptionDate: function(exceptionStartDate, targetStartDate, startDateTimeZone) {
  1455. exceptionStartDate = this.fire("convertDateByTimezoneBack", exceptionStartDate, startDateTimeZone);
  1456. var appointmentStartDate = this.fire("convertDateByTimezoneBack", targetStartDate, startDateTimeZone);
  1457. exceptionStartDate.setHours(appointmentStartDate.getHours(), appointmentStartDate.getMinutes(), appointmentStartDate.getSeconds(), appointmentStartDate.getMilliseconds());
  1458. var timezoneDiff = targetStartDate.getTimezoneOffset() - exceptionStartDate.getTimezoneOffset();
  1459. exceptionStartDate = new Date(exceptionStartDate.getTime() - timezoneDiff * toMs("minute"));
  1460. return _date_serialization2.default.serializeDate(exceptionStartDate, UTC_FULL_DATE_FORMAT)
  1461. },
  1462. _showRecurrenceChangeConfirm: function(isDeleted) {
  1463. var message = _message2.default.format(isDeleted ? "dxScheduler-confirmRecurrenceDeleteMessage" : "dxScheduler-confirmRecurrenceEditMessage");
  1464. var seriesText = _message2.default.format(isDeleted ? "dxScheduler-confirmRecurrenceDeleteSeries" : "dxScheduler-confirmRecurrenceEditSeries");
  1465. var occurrenceText = _message2.default.format(isDeleted ? "dxScheduler-confirmRecurrenceDeleteOccurrence" : "dxScheduler-confirmRecurrenceEditOccurrence");
  1466. return _dialog2.default.custom({
  1467. messageHtml: message,
  1468. showCloseButton: true,
  1469. showTitle: true,
  1470. buttons: [{
  1471. text: seriesText,
  1472. onClick: function() {
  1473. return true
  1474. }
  1475. }, {
  1476. text: occurrenceText,
  1477. onClick: function() {
  1478. return false
  1479. }
  1480. }]
  1481. }).show()
  1482. },
  1483. _getUpdatedData: function(options) {
  1484. var target = options.data || options;
  1485. var cellData = this.getTargetCellData();
  1486. var targetAllDay = this.fire("getField", "allDay", target);
  1487. var targetStartDate = new Date(this.fire("getField", "startDate", target));
  1488. var targetEndDate = new Date(this.fire("getField", "endDate", target));
  1489. var date = cellData.date || targetStartDate;
  1490. var duration = targetEndDate.getTime() - targetStartDate.getTime();
  1491. if (this._workSpace.keepOriginalHours()) {
  1492. var diff = targetStartDate.getTime() - _date2.default.trimTime(targetStartDate).getTime();
  1493. date = new Date(_date2.default.trimTime(date).getTime() + diff)
  1494. }
  1495. var updatedData = {};
  1496. var allDay = cellData.allDay;
  1497. this.fire("setField", "allDay", updatedData, allDay);
  1498. this.fire("setField", "startDate", updatedData, date);
  1499. var endDate = new Date(date.getTime() + duration);
  1500. if (this.appointmentTakesAllDay(target) && !updatedData.allDay && this._workSpace.supportAllDayRow()) {
  1501. endDate = this._workSpace.calculateEndDate(date)
  1502. }
  1503. if (targetAllDay && !this._workSpace.supportAllDayRow() && !this._workSpace.keepOriginalHours()) {
  1504. var dateCopy = new Date(date);
  1505. dateCopy.setHours(0);
  1506. endDate = new Date(dateCopy.getTime() + duration);
  1507. if (0 !== endDate.getHours()) {
  1508. endDate.setHours(this._getCurrentViewOption("endDayHour"))
  1509. }
  1510. }
  1511. this.fire("setField", "endDate", updatedData, endDate);
  1512. this._resourcesManager.setResourcesToItem(updatedData, cellData.groups);
  1513. return updatedData
  1514. },
  1515. _getCoordinates: function(initialDates, dates, appointmentResources, allDay) {
  1516. var result = [];
  1517. for (var i = 0; i < dates.length; i++) {
  1518. var currentCoords = this._workSpace.getCoordinatesByDateInGroup(dates[i], appointmentResources, allDay);
  1519. for (var j = 0; j < currentCoords.length; j++) {
  1520. (0, _extend.extend)(currentCoords[j], {
  1521. startDate: dates[i],
  1522. initialStartDate: initialDates[i]
  1523. })
  1524. }
  1525. result = result.concat(currentCoords)
  1526. }
  1527. return result
  1528. },
  1529. _isAppointmentRecurrence: function(appointmentData) {
  1530. var recurrenceRule = this.fire("getField", "recurrenceRule", appointmentData);
  1531. return recurrenceRule && _utils2.default.getRecurrenceRule(recurrenceRule).isValid
  1532. },
  1533. _getSingleAppointmentData: function(appointmentData, options) {
  1534. options = options || {};
  1535. var $appointment = options.$appointment;
  1536. var updatedData = options.skipDateCalculation ? {} : this._getUpdatedData(options);
  1537. var resultAppointmentData = (0, _extend.extend)({}, appointmentData, updatedData);
  1538. var allDay = this.fire("getField", "allDay", appointmentData);
  1539. var isAllDay = this._workSpace.supportAllDayRow() && allDay;
  1540. var startDate = new Date(this.fire("getField", "startDate", resultAppointmentData));
  1541. var endDate = new Date(this.fire("getField", "endDate", resultAppointmentData));
  1542. var appointmentDuration = endDate.getTime() - startDate.getTime();
  1543. var updatedStartDate;
  1544. var appointmentStartDate;
  1545. if (_type2.default.isDefined($appointment) && this._needUpdateAppointmentData($appointment)) {
  1546. var apptDataCalculator = this.getRenderingStrategyInstance().getAppointmentDataCalculator();
  1547. if (_type2.default.isFunction(apptDataCalculator)) {
  1548. updatedStartDate = apptDataCalculator($appointment, startDate).startDate
  1549. } else {
  1550. var coordinates = _translator2.default.locate($appointment);
  1551. updatedStartDate = new Date(this._workSpace.getCellDataByCoordinates(coordinates, isAllDay).startDate);
  1552. if ($appointment.hasClass("dx-scheduler-appointment-reduced")) {
  1553. appointmentStartDate = $appointment.data("dxAppointmentStartDate");
  1554. if (appointmentStartDate) {
  1555. updatedStartDate = appointmentStartDate
  1556. }
  1557. }
  1558. if (this._isAppointmentRecurrence(appointmentData)) {
  1559. appointmentStartDate = $appointment.data("dxAppointmentSettings") && $appointment.data("dxAppointmentSettings").startDate;
  1560. if (appointmentStartDate) {
  1561. updatedStartDate = appointmentStartDate
  1562. }
  1563. }
  1564. if (!options.skipHoursProcessing) {
  1565. this.fire("convertDateByTimezoneBack", updatedStartDate, this.fire("getField", "startDateTimeZone", appointmentData))
  1566. }
  1567. }
  1568. }
  1569. if (!updatedStartDate && options.startDate) {
  1570. updatedStartDate = options.startDate
  1571. }
  1572. if (updatedStartDate) {
  1573. this.fire("setField", "startDate", resultAppointmentData, updatedStartDate);
  1574. this.fire("setField", "endDate", resultAppointmentData, new Date(updatedStartDate.getTime() + appointmentDuration))
  1575. }
  1576. return resultAppointmentData
  1577. },
  1578. _needUpdateAppointmentData: function($appointment) {
  1579. return $appointment.hasClass("dx-scheduler-appointment-compact") || $appointment.hasClass("dx-scheduler-appointment-recurrence")
  1580. },
  1581. _getNormalizedTemplateArgs: function(options) {
  1582. var args = this.callBase(options);
  1583. if ("targetedAppointmentData" in options) {
  1584. args.push(options.targetedAppointmentData)
  1585. }
  1586. if ("currentIndex" in options) {
  1587. args.push(options.currentIndex)
  1588. }
  1589. return args
  1590. },
  1591. subscribe: function(subject, action) {
  1592. this._subscribes[subject] = _uiScheduler2.default[subject] = action
  1593. },
  1594. fire: function(subject) {
  1595. var callback = this._subscribes[subject];
  1596. var args = Array.prototype.slice.call(arguments);
  1597. if (!_type2.default.isFunction(callback)) {
  1598. throw _ui2.default.Error("E1031", subject)
  1599. }
  1600. return callback.apply(this, args.slice(1))
  1601. },
  1602. getTargetCellData: function() {
  1603. return this._workSpace.getDataByDroppableCell()
  1604. },
  1605. _updateAppointment: function(target, appointment, onUpdatePrevented) {
  1606. var updatingOptions = {
  1607. newData: appointment,
  1608. oldData: (0, _extend.extend)({}, target),
  1609. cancel: false
  1610. };
  1611. var performFailAction = function(err) {
  1612. if (_type2.default.isFunction(onUpdatePrevented)) {
  1613. onUpdatePrevented.call(this)
  1614. }
  1615. if (err && "Error" === err.name) {
  1616. throw err
  1617. }
  1618. }.bind(this);
  1619. this._actions.onAppointmentUpdating(updatingOptions);
  1620. this._processActionResult(updatingOptions, function(canceled) {
  1621. if (!canceled) {
  1622. this._expandAllDayPanel(appointment);
  1623. try {
  1624. this._appointmentModel.update(target, appointment).always(function(e) {
  1625. this._executeActionWhenOperationIsCompleted(this._actions.onAppointmentUpdated, appointment, e)
  1626. }.bind(this)).fail(function() {
  1627. performFailAction()
  1628. })
  1629. } catch (err) {
  1630. performFailAction(err)
  1631. }
  1632. } else {
  1633. performFailAction()
  1634. }
  1635. })
  1636. },
  1637. _processActionResult: function(actionOptions, callback) {
  1638. var _this8 = this;
  1639. if (_type2.default.isPromise(actionOptions.cancel)) {
  1640. when(_deferred2.default.fromPromise(actionOptions.cancel)).always(function(cancel) {
  1641. if (!_type2.default.isDefined(cancel)) {
  1642. cancel = "rejected" === actionOptions.cancel.state()
  1643. }
  1644. callback.call(_this8, cancel)
  1645. })
  1646. } else {
  1647. callback.call(this, actionOptions.cancel)
  1648. }
  1649. },
  1650. _expandAllDayPanel: function(appointment) {
  1651. if (!this._isAllDayExpanded(this.getFilteredItems()) && this.appointmentTakesAllDay(appointment)) {
  1652. this._workSpace.option("allDayExpanded", true)
  1653. }
  1654. },
  1655. _executeActionWhenOperationIsCompleted: function(action, appointment, e) {
  1656. var options = {
  1657. appointmentData: appointment
  1658. };
  1659. var isError = e && "Error" === e.name;
  1660. if (isError) {
  1661. options.error = e
  1662. } else {
  1663. if (this._popup && this._popup.option("visible")) {
  1664. this._popup.hide()
  1665. }
  1666. }
  1667. action(options);
  1668. this._fireContentReadyAction()
  1669. },
  1670. _showAppointmentPopup: function(data, showButtons, processTimeZone) {
  1671. if (!this._popup) {
  1672. this._createPopup(data, processTimeZone)
  1673. }
  1674. var toolbarItems = [];
  1675. var showCloseButton = true;
  1676. if (!_type2.default.isDefined(showButtons) || showButtons) {
  1677. toolbarItems = this._getPopupToolbarItems();
  1678. showCloseButton = this._popup.initialOption("showCloseButton")
  1679. }
  1680. this._popup.option({
  1681. toolbarItems: toolbarItems,
  1682. showCloseButton: showCloseButton
  1683. });
  1684. if (this._appointmentForm) {
  1685. this._createOrUpdateForm(data, processTimeZone)
  1686. } else {
  1687. this._initDynamicPopupTemplate(data, processTimeZone);
  1688. this._popup.option(this._popupConfig(data))
  1689. }
  1690. this._popup.show()
  1691. },
  1692. getAppointmentPopup: function() {
  1693. return this._popup
  1694. },
  1695. getAppointmentDetailsForm: function() {
  1696. return this._appointmentForm
  1697. },
  1698. getUpdatedAppointment: function() {
  1699. return this._appointmentModel.getUpdatedAppointment()
  1700. },
  1701. getUpdatedAppointmentKeys: function() {
  1702. return this._appointmentModel.getUpdatedAppointmentKeys()
  1703. },
  1704. getAppointmentsInstance: function() {
  1705. return this._appointments
  1706. },
  1707. getResourceManager: function() {
  1708. return this._resourcesManager
  1709. },
  1710. getLayoutManager: function() {
  1711. return this._layoutManager
  1712. },
  1713. getRenderingStrategyInstance: function() {
  1714. return this._layoutManager.getRenderingStrategyInstance()
  1715. },
  1716. getFilteredItems: function() {
  1717. return this._filteredItems
  1718. },
  1719. getActions: function() {
  1720. return this._actions
  1721. },
  1722. appointmentTakesAllDay: function(appointment) {
  1723. return this._appointmentModel.appointmentTakesAllDay(appointment, this._getCurrentViewOption("startDayHour"), this._getCurrentViewOption("endDayHour"))
  1724. },
  1725. _getStartDate: function(appointment, skipNormalize) {
  1726. var startDate = this.fire("getField", "startDate", appointment);
  1727. var startDateTimeZone = this.fire("getField", "startDateTimeZone", appointment);
  1728. startDate = _date2.default.makeDate(startDate);
  1729. startDate = this.fire("convertDateByTimezone", startDate, startDateTimeZone);
  1730. !skipNormalize && this.fire("updateAppointmentStartDate", {
  1731. startDate: startDate,
  1732. appointment: appointment,
  1733. callback: function(result) {
  1734. startDate = result
  1735. }
  1736. });
  1737. return startDate
  1738. },
  1739. _getEndDate: function(appointment, skipNormalize) {
  1740. var endDate = new Date(this.fire("getField", "endDate", appointment));
  1741. var startDate = new Date(this.fire("getField", "startDate", appointment));
  1742. var isSameDate = _date2.default.sameDate(startDate, endDate);
  1743. if (endDate) {
  1744. var endDateTimeZone = this.fire("getField", "endDateTimeZone", appointment);
  1745. endDate = _date2.default.makeDate(endDate);
  1746. endDate = this.fire("convertDateByTimezone", endDate, endDateTimeZone);
  1747. !skipNormalize && this.fire("updateAppointmentEndDate", {
  1748. endDate: endDate,
  1749. isSameDate: isSameDate,
  1750. callback: function(result) {
  1751. endDate = result
  1752. }
  1753. })
  1754. }
  1755. return endDate
  1756. },
  1757. _getRecurrenceException: function(appointmentData) {
  1758. var recurrenceException = this.fire("getField", "recurrenceException", appointmentData);
  1759. if (recurrenceException) {
  1760. var startDate = this.fire("getField", "startDate", appointmentData);
  1761. var exceptions = recurrenceException.split(",");
  1762. var startDateTimeZone = this.fire("getField", "startDateTimeZone", appointmentData);
  1763. var exceptionByStartDate = this.fire("convertDateByTimezone", startDate, startDateTimeZone);
  1764. for (var i = 0; i < exceptions.length; i++) {
  1765. exceptions[i] = this._convertRecurrenceException(exceptions[i], exceptionByStartDate, startDateTimeZone)
  1766. }
  1767. recurrenceException = exceptions.join()
  1768. }
  1769. return recurrenceException
  1770. },
  1771. _convertRecurrenceException: function(exception, exceptionByStartDate, startDateTimeZone) {
  1772. exception = exception.replace(/\s/g, "");
  1773. exception = _date_serialization2.default.deserializeDate(exception);
  1774. exception = this.fire("convertDateByTimezone", exception, startDateTimeZone);
  1775. exception.setHours(exceptionByStartDate.getHours());
  1776. exception = _date_serialization2.default.serializeDate(exception, FULL_DATE_FORMAT);
  1777. return exception
  1778. },
  1779. recurrenceEditorVisibilityChanged: function(visible) {
  1780. if (this._appointmentForm) {
  1781. this._appointmentForm.$element().find("." + RECURRENCE_EDITOR_ITEM_CLASS).toggleClass(RECURRENCE_EDITOR_OPENED_ITEM_CLASS, visible)
  1782. }
  1783. },
  1784. resizePopup: function() {
  1785. if (this.getAppointmentPopup()) {
  1786. _dom2.default.triggerResizeEvent(this.getAppointmentPopup().$element())
  1787. }
  1788. },
  1789. dayHasAppointment: function(day, appointment, trimTime) {
  1790. var startDate = new Date(this.fire("getField", "startDate", appointment));
  1791. var endDate = new Date(this.fire("getField", "endDate", appointment));
  1792. var startDateTimeZone = this.fire("getField", "startDateTimeZone", appointment);
  1793. var endDateTimeZone = this.fire("getField", "endDateTimeZone", appointment);
  1794. startDate = this.fire("convertDateByTimezone", startDate, startDateTimeZone);
  1795. endDate = this.fire("convertDateByTimezone", endDate, endDateTimeZone);
  1796. if (day.getTime() === endDate.getTime()) {
  1797. return startDate.getTime() === endDate.getTime()
  1798. }
  1799. if (trimTime) {
  1800. day = _date2.default.trimTime(day);
  1801. startDate = _date2.default.trimTime(startDate);
  1802. endDate = _date2.default.trimTime(endDate)
  1803. }
  1804. var dayTimeStamp = day.getTime();
  1805. var startDateTimeStamp = startDate.getTime();
  1806. var endDateTimeStamp = endDate.getTime();
  1807. return (0, _array.inArray)(dayTimeStamp, [startDateTimeStamp, endDateTimeStamp]) > -1 || startDateTimeStamp < dayTimeStamp && endDateTimeStamp > dayTimeStamp
  1808. },
  1809. setTargetedAppointmentResources: function(targetedAppointment, appointmentElement, appointmentIndex) {
  1810. var groups = this._getCurrentViewOption("groups");
  1811. if (groups && groups.length) {
  1812. var resourcesSetter = this._resourcesManager._dataAccessors.setter;
  1813. var workSpace = this._workSpace;
  1814. var getGroups;
  1815. var setResourceCallback;
  1816. if (this._isAgenda()) {
  1817. getGroups = function() {
  1818. var apptSettings = this.getLayoutManager()._positionMap[appointmentIndex];
  1819. return workSpace._getCellGroups(apptSettings[0].groupIndex)
  1820. };
  1821. setResourceCallback = function(_, group) {
  1822. resourcesSetter[group.name](targetedAppointment, group.id)
  1823. }
  1824. } else {
  1825. getGroups = function() {
  1826. var setting = (0, _renderer2.default)(appointmentElement).data("dxAppointmentSettings") || {};
  1827. return workSpace.getCellDataByCoordinates({
  1828. left: setting.left,
  1829. top: setting.top
  1830. }).groups
  1831. };
  1832. setResourceCallback = function(field, value) {
  1833. resourcesSetter[field](targetedAppointment, value)
  1834. }
  1835. }(0, _iterator.each)(getGroups.call(this), setResourceCallback)
  1836. }
  1837. },
  1838. getStartViewDate: function() {
  1839. return this._workSpace.getStartViewDate()
  1840. },
  1841. getEndViewDate: function() {
  1842. return this._workSpace.getEndViewDate()
  1843. },
  1844. showAppointmentPopup: function(appointmentData, createNewAppointment, currentAppointmentData) {
  1845. var singleAppointment = currentAppointmentData || this._getSingleAppointmentData(appointmentData, {
  1846. skipDateCalculation: true
  1847. });
  1848. var startDate = this.fire("getField", "startDate", currentAppointmentData || appointmentData);
  1849. this._checkRecurringAppointment(appointmentData, singleAppointment, startDate, function() {
  1850. if (createNewAppointment || _type2.default.isEmptyObject(appointmentData)) {
  1851. delete this._editAppointmentData;
  1852. this._editing.allowAdding && this._showAppointmentPopup(appointmentData, true, false)
  1853. } else {
  1854. this._editAppointmentData = appointmentData;
  1855. this._showAppointmentPopup(appointmentData, this._editing.allowUpdating, true)
  1856. }
  1857. }.bind(this), false, true)
  1858. },
  1859. hideAppointmentPopup: function(saveChanges) {
  1860. if (!this._popup || !this._popup.option("visible")) {
  1861. return
  1862. }
  1863. if (saveChanges) {
  1864. this._saveChanges()
  1865. }
  1866. this._popup.hide()
  1867. },
  1868. showAppointmentTooltip: function(appointmentData, target, currentAppointmentData) {
  1869. if (appointmentData) {
  1870. this.showAppointmentTooltipCore(target, [{
  1871. color: this._appointments._tryGetAppointmentColor(target),
  1872. data: appointmentData,
  1873. currentData: currentAppointmentData
  1874. }], true)
  1875. }
  1876. },
  1877. showAppointmentTooltipCore: function(target, data, isSingleBehavior) {
  1878. this._appointmentTooltip.show(target, data, isSingleBehavior)
  1879. },
  1880. hideAppointmentTooltip: function() {
  1881. this._appointmentTooltip.hide()
  1882. },
  1883. scrollToTime: function(hours, minutes, date) {
  1884. this._workSpace.scrollToTime(hours, minutes, date)
  1885. },
  1886. addAppointment: function(appointment) {
  1887. var text = this.fire("getField", "text", appointment);
  1888. if (!text) {
  1889. this.fire("setField", "text", appointment, "")
  1890. }
  1891. this._convertDatesByTimezoneBack(true, appointment);
  1892. var addingOptions = {
  1893. appointmentData: appointment,
  1894. cancel: false
  1895. };
  1896. this._actions.onAppointmentAdding(addingOptions);
  1897. this._processActionResult(addingOptions, function(canceled) {
  1898. if (!canceled) {
  1899. this._expandAllDayPanel(appointment);
  1900. this._appointmentModel.add(appointment, {
  1901. value: this._getTimezoneOffsetByOption(),
  1902. clientOffset: this.fire("getClientTimezoneOffset")
  1903. }).always(function(e) {
  1904. this._executeActionWhenOperationIsCompleted(this._actions.onAppointmentAdded, appointment, e)
  1905. }.bind(this))
  1906. }
  1907. })
  1908. },
  1909. updateAppointment: function(target, appointment) {
  1910. this._updateAppointment(target, appointment)
  1911. },
  1912. deleteAppointment: function(appointment) {
  1913. var deletingOptions = {
  1914. appointmentData: appointment,
  1915. cancel: false
  1916. };
  1917. this._actions.onAppointmentDeleting(deletingOptions);
  1918. this._processActionResult(deletingOptions, function(canceled) {
  1919. if (!canceled) {
  1920. this._appointmentModel.remove(appointment).always(function(e) {
  1921. this._executeActionWhenOperationIsCompleted(this._actions.onAppointmentDeleted, appointment, e)
  1922. }.bind(this))
  1923. }
  1924. })
  1925. },
  1926. focus: function() {
  1927. if (this._editAppointmentData) {
  1928. this._appointments.focus()
  1929. } else {
  1930. this._workSpace.focus()
  1931. }
  1932. },
  1933. getFirstDayOfWeek: function() {
  1934. return _type2.default.isDefined(this.option("firstDayOfWeek")) ? this.option("firstDayOfWeek") : _date4.default.firstDayOfWeekIndex()
  1935. }
  1936. }).include(_async_template_mixin2.default, _data_helper2.default);
  1937. (0, _component_registrator2.default)("dxScheduler", Scheduler);
  1938. module.exports = Scheduler;