@syncfusion/ej2-schedule 30.2.4 → 31.1.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (308) hide show
  1. package/dist/ej2-schedule.min.js +2 -2
  2. package/dist/ej2-schedule.umd.min.js +2 -2
  3. package/dist/ej2-schedule.umd.min.js.map +1 -1
  4. package/dist/es6/ej2-schedule.es2015.js +132 -43
  5. package/dist/es6/ej2-schedule.es2015.js.map +1 -1
  6. package/dist/es6/ej2-schedule.es5.js +132 -43
  7. package/dist/es6/ej2-schedule.es5.js.map +1 -1
  8. package/dist/global/ej2-schedule.min.js +2 -2
  9. package/dist/global/ej2-schedule.min.js.map +1 -1
  10. package/dist/global/index.d.ts +1 -1
  11. package/dist/ts/common/calendar-util.d.ts +92 -0
  12. package/dist/ts/common/calendar-util.ts +261 -0
  13. package/dist/ts/common/index.d.ts +4 -0
  14. package/dist/ts/common/index.ts +4 -0
  15. package/dist/ts/components.d.ts +5 -0
  16. package/dist/ts/components.ts +5 -0
  17. package/dist/ts/index.d.ts +6 -0
  18. package/dist/ts/index.ts +7 -0
  19. package/dist/ts/recurrence-editor/date-generator.d.ts +76 -0
  20. package/dist/ts/recurrence-editor/date-generator.ts +1699 -0
  21. package/dist/ts/recurrence-editor/index.d.ts +6 -0
  22. package/dist/ts/recurrence-editor/index.ts +6 -0
  23. package/dist/ts/recurrence-editor/recurrence-editor-model.d.ts +112 -0
  24. package/dist/ts/recurrence-editor/recurrence-editor.d.ts +245 -0
  25. package/dist/ts/recurrence-editor/recurrence-editor.ts +1257 -0
  26. package/dist/ts/schedule/actions/action-base.d.ts +44 -0
  27. package/dist/ts/schedule/actions/action-base.ts +493 -0
  28. package/dist/ts/schedule/actions/crud.d.ts +41 -0
  29. package/dist/ts/schedule/actions/crud.ts +784 -0
  30. package/dist/ts/schedule/actions/data.d.ts +63 -0
  31. package/dist/ts/schedule/actions/data.ts +128 -0
  32. package/dist/ts/schedule/actions/drag.d.ts +75 -0
  33. package/dist/ts/schedule/actions/drag.ts +1401 -0
  34. package/dist/ts/schedule/actions/keyboard.d.ts +100 -0
  35. package/dist/ts/schedule/actions/keyboard.ts +1435 -0
  36. package/dist/ts/schedule/actions/resize.d.ts +27 -0
  37. package/dist/ts/schedule/actions/resize.ts +602 -0
  38. package/dist/ts/schedule/actions/scroll.d.ts +69 -0
  39. package/dist/ts/schedule/actions/scroll.ts +105 -0
  40. package/dist/ts/schedule/actions/touch.d.ts +32 -0
  41. package/dist/ts/schedule/actions/touch.ts +314 -0
  42. package/dist/ts/schedule/actions/virtual-scroll.d.ts +55 -0
  43. package/dist/ts/schedule/actions/virtual-scroll.ts +596 -0
  44. package/dist/ts/schedule/actions/work-cells.d.ts +14 -0
  45. package/dist/ts/schedule/actions/work-cells.ts +151 -0
  46. package/dist/ts/schedule/base/constant.d.ts +102 -0
  47. package/dist/ts/schedule/base/constant.ts +103 -0
  48. package/dist/ts/schedule/base/css-constant.d.ts +475 -0
  49. package/dist/ts/schedule/base/css-constant.ts +475 -0
  50. package/dist/ts/schedule/base/interface.d.ts +673 -0
  51. package/dist/ts/schedule/base/interface.ts +738 -0
  52. package/dist/ts/schedule/base/resource.d.ts +59 -0
  53. package/dist/ts/schedule/base/resource.ts +1091 -0
  54. package/dist/ts/schedule/base/schedule-model.d.ts +930 -0
  55. package/dist/ts/schedule/base/schedule.d.ts +1967 -0
  56. package/dist/ts/schedule/base/schedule.ts +4221 -0
  57. package/dist/ts/schedule/base/type.d.ts +134 -0
  58. package/dist/ts/schedule/base/type.ts +142 -0
  59. package/dist/ts/schedule/base/util.d.ts +266 -0
  60. package/dist/ts/schedule/base/util.ts +492 -0
  61. package/dist/ts/schedule/event-renderer/agenda-base.d.ts +15 -0
  62. package/dist/ts/schedule/event-renderer/agenda-base.ts +423 -0
  63. package/dist/ts/schedule/event-renderer/event-base.d.ts +101 -0
  64. package/dist/ts/schedule/event-renderer/event-base.ts +1501 -0
  65. package/dist/ts/schedule/event-renderer/inline-edit.d.ts +23 -0
  66. package/dist/ts/schedule/event-renderer/inline-edit.ts +287 -0
  67. package/dist/ts/schedule/event-renderer/month.d.ts +60 -0
  68. package/dist/ts/schedule/event-renderer/month.ts +760 -0
  69. package/dist/ts/schedule/event-renderer/timeline-view.d.ts +51 -0
  70. package/dist/ts/schedule/event-renderer/timeline-view.ts +606 -0
  71. package/dist/ts/schedule/event-renderer/vertical-view.d.ts +57 -0
  72. package/dist/ts/schedule/event-renderer/vertical-view.ts +898 -0
  73. package/dist/ts/schedule/event-renderer/year.d.ts +27 -0
  74. package/dist/ts/schedule/event-renderer/year.ts +623 -0
  75. package/dist/ts/schedule/exports/calendar-export.d.ts +16 -0
  76. package/dist/ts/schedule/exports/calendar-export.ts +160 -0
  77. package/dist/ts/schedule/exports/calendar-import.d.ts +18 -0
  78. package/dist/ts/schedule/exports/calendar-import.ts +277 -0
  79. package/dist/ts/schedule/exports/excel-export.d.ts +14 -0
  80. package/dist/ts/schedule/exports/excel-export.ts +89 -0
  81. package/dist/ts/schedule/exports/index.d.ts +7 -0
  82. package/dist/ts/schedule/exports/index.ts +7 -0
  83. package/dist/ts/schedule/exports/print.d.ts +20 -0
  84. package/dist/ts/schedule/exports/print.ts +233 -0
  85. package/dist/ts/schedule/index.d.ts +26 -0
  86. package/dist/ts/schedule/index.ts +26 -0
  87. package/dist/ts/schedule/models/event-settings-model.d.ts +165 -0
  88. package/dist/ts/schedule/models/event-settings.d.ts +149 -0
  89. package/dist/ts/schedule/models/event-settings.ts +187 -0
  90. package/dist/ts/schedule/models/field-options-model.d.ts +37 -0
  91. package/dist/ts/schedule/models/field-options.d.ts +31 -0
  92. package/dist/ts/schedule/models/field-options.ts +41 -0
  93. package/dist/ts/schedule/models/fields-model.d.ts +129 -0
  94. package/dist/ts/schedule/models/fields.d.ts +117 -0
  95. package/dist/ts/schedule/models/fields.ts +149 -0
  96. package/dist/ts/schedule/models/group-model.d.ts +69 -0
  97. package/dist/ts/schedule/models/group.d.ts +60 -0
  98. package/dist/ts/schedule/models/group.ts +75 -0
  99. package/dist/ts/schedule/models/header-rows-model.d.ts +33 -0
  100. package/dist/ts/schedule/models/header-rows.d.ts +30 -0
  101. package/dist/ts/schedule/models/header-rows.ts +35 -0
  102. package/dist/ts/schedule/models/models.d.ts +14 -0
  103. package/dist/ts/schedule/models/models.ts +15 -0
  104. package/dist/ts/schedule/models/quick-info-templates-model.d.ts +52 -0
  105. package/dist/ts/schedule/models/quick-info-templates.d.ts +47 -0
  106. package/dist/ts/schedule/models/quick-info-templates.ts +56 -0
  107. package/dist/ts/schedule/models/resources-model.d.ts +122 -0
  108. package/dist/ts/schedule/models/resources.d.ts +106 -0
  109. package/dist/ts/schedule/models/resources.ts +138 -0
  110. package/dist/ts/schedule/models/time-scale-model.d.ts +57 -0
  111. package/dist/ts/schedule/models/time-scale.d.ts +50 -0
  112. package/dist/ts/schedule/models/time-scale.ts +61 -0
  113. package/dist/ts/schedule/models/toolbar-model.d.ts +196 -0
  114. package/dist/ts/schedule/models/toolbar.d.ts +176 -0
  115. package/dist/ts/schedule/models/toolbar.ts +196 -0
  116. package/dist/ts/schedule/models/views-model.d.ts +370 -0
  117. package/dist/ts/schedule/models/views.d.ts +335 -0
  118. package/dist/ts/schedule/models/views.ts +408 -0
  119. package/dist/ts/schedule/models/work-hours-model.d.ts +29 -0
  120. package/dist/ts/schedule/models/work-hours.d.ts +24 -0
  121. package/dist/ts/schedule/models/work-hours.ts +31 -0
  122. package/dist/ts/schedule/popups/event-tooltip.d.ts +16 -0
  123. package/dist/ts/schedule/popups/event-tooltip.ts +203 -0
  124. package/dist/ts/schedule/popups/event-window.d.ts +118 -0
  125. package/dist/ts/schedule/popups/event-window.ts +2055 -0
  126. package/dist/ts/schedule/popups/form-validator.d.ts +16 -0
  127. package/dist/ts/schedule/popups/form-validator.ts +110 -0
  128. package/dist/ts/schedule/popups/quick-popups.d.ts +78 -0
  129. package/dist/ts/schedule/popups/quick-popups.ts +1470 -0
  130. package/dist/ts/schedule/renderer/agenda.d.ts +45 -0
  131. package/dist/ts/schedule/renderer/agenda.ts +497 -0
  132. package/dist/ts/schedule/renderer/day.d.ts +20 -0
  133. package/dist/ts/schedule/renderer/day.ts +28 -0
  134. package/dist/ts/schedule/renderer/header-renderer.d.ts +48 -0
  135. package/dist/ts/schedule/renderer/header-renderer.ts +736 -0
  136. package/dist/ts/schedule/renderer/month-agenda.d.ts +29 -0
  137. package/dist/ts/schedule/renderer/month-agenda.ts +184 -0
  138. package/dist/ts/schedule/renderer/month.d.ts +61 -0
  139. package/dist/ts/schedule/renderer/month.ts +766 -0
  140. package/dist/ts/schedule/renderer/renderer.d.ts +13 -0
  141. package/dist/ts/schedule/renderer/renderer.ts +165 -0
  142. package/dist/ts/schedule/renderer/timeline-header-row.d.ts +15 -0
  143. package/dist/ts/schedule/renderer/timeline-header-row.ts +132 -0
  144. package/dist/ts/schedule/renderer/timeline-month.d.ts +29 -0
  145. package/dist/ts/schedule/renderer/timeline-month.ts +184 -0
  146. package/dist/ts/schedule/renderer/timeline-view.d.ts +31 -0
  147. package/dist/ts/schedule/renderer/timeline-view.ts +308 -0
  148. package/dist/ts/schedule/renderer/timeline-year.d.ts +22 -0
  149. package/dist/ts/schedule/renderer/timeline-year.ts +450 -0
  150. package/dist/ts/schedule/renderer/vertical-view.d.ts +63 -0
  151. package/dist/ts/schedule/renderer/vertical-view.ts +911 -0
  152. package/dist/ts/schedule/renderer/view-base.d.ts +83 -0
  153. package/dist/ts/schedule/renderer/view-base.ts +709 -0
  154. package/dist/ts/schedule/renderer/week.d.ts +22 -0
  155. package/dist/ts/schedule/renderer/week.ts +35 -0
  156. package/dist/ts/schedule/renderer/work-week.d.ts +22 -0
  157. package/dist/ts/schedule/renderer/work-week.ts +36 -0
  158. package/dist/ts/schedule/renderer/year.d.ts +46 -0
  159. package/dist/ts/schedule/renderer/year.ts +470 -0
  160. package/dist/ts/schedule/timezone/timezone.d.ts +16 -0
  161. package/dist/ts/schedule/timezone/timezone.ts +313 -0
  162. package/package.json +56 -21
  163. package/src/schedule/actions/action-base.js +3 -0
  164. package/src/schedule/actions/drag.js +11 -4
  165. package/src/schedule/actions/keyboard.js +1 -1
  166. package/src/schedule/actions/resize.js +9 -5
  167. package/src/schedule/actions/virtual-scroll.js +3 -0
  168. package/src/schedule/base/css-constant.d.ts +2 -0
  169. package/src/schedule/base/css-constant.js +2 -0
  170. package/src/schedule/base/schedule.js +15 -1
  171. package/src/schedule/event-renderer/agenda-base.d.ts +1 -1
  172. package/src/schedule/event-renderer/agenda-base.js +5 -4
  173. package/src/schedule/event-renderer/inline-edit.js +11 -6
  174. package/src/schedule/event-renderer/month.js +5 -3
  175. package/src/schedule/event-renderer/vertical-view.js +3 -0
  176. package/src/schedule/event-renderer/year.d.ts +2 -0
  177. package/src/schedule/event-renderer/year.js +28 -4
  178. package/src/schedule/popups/event-tooltip.js +4 -0
  179. package/src/schedule/popups/event-window.js +2 -2
  180. package/src/schedule/popups/quick-popups.js +5 -1
  181. package/src/schedule/renderer/agenda.js +3 -2
  182. package/src/schedule/renderer/month.js +9 -7
  183. package/src/schedule/renderer/vertical-view.js +1 -1
  184. package/src/schedule/renderer/view-base.d.ts +2 -0
  185. package/src/schedule/renderer/view-base.js +9 -0
  186. package/src/schedule/renderer/year.js +3 -2
  187. package/styles/bds-lite.css +11 -8
  188. package/styles/bds.css +11 -8
  189. package/styles/bootstrap-dark-lite.css +12 -9
  190. package/styles/bootstrap-dark.css +12 -9
  191. package/styles/bootstrap-lite.css +12 -9
  192. package/styles/bootstrap.css +12 -9
  193. package/styles/bootstrap4-lite.css +11 -8
  194. package/styles/bootstrap4.css +11 -8
  195. package/styles/bootstrap5-dark-lite.css +11 -8
  196. package/styles/bootstrap5-dark.css +11 -8
  197. package/styles/bootstrap5-lite.css +11 -8
  198. package/styles/bootstrap5.3-lite.css +11 -8
  199. package/styles/bootstrap5.3.css +11 -8
  200. package/styles/bootstrap5.css +11 -8
  201. package/styles/fabric-dark-lite.css +12 -9
  202. package/styles/fabric-dark.css +12 -9
  203. package/styles/fabric-lite.css +12 -9
  204. package/styles/fabric.css +12 -9
  205. package/styles/fluent-dark-lite.css +13 -10
  206. package/styles/fluent-dark.css +13 -10
  207. package/styles/fluent-lite.css +13 -10
  208. package/styles/fluent.css +13 -10
  209. package/styles/fluent2-lite.css +11 -8
  210. package/styles/fluent2.css +11 -8
  211. package/styles/highcontrast-light-lite.css +12 -9
  212. package/styles/highcontrast-light.css +12 -9
  213. package/styles/highcontrast-lite.css +12 -9
  214. package/styles/highcontrast.css +12 -9
  215. package/styles/material-dark-lite.css +12 -9
  216. package/styles/material-dark.css +12 -9
  217. package/styles/material-lite.css +12 -9
  218. package/styles/material.css +12 -9
  219. package/styles/material3-dark-lite.css +11 -8
  220. package/styles/material3-dark.css +11 -8
  221. package/styles/material3-lite.css +11 -8
  222. package/styles/material3.css +11 -8
  223. package/styles/recurrence-editor/_bds-definition.scss +1 -0
  224. package/styles/recurrence-editor/_bootstrap-dark-definition.scss +1 -0
  225. package/styles/recurrence-editor/_bootstrap-definition.scss +1 -0
  226. package/styles/recurrence-editor/_bootstrap4-definition.scss +1 -0
  227. package/styles/recurrence-editor/_bootstrap5-definition.scss +1 -0
  228. package/styles/recurrence-editor/_bootstrap5.3-definition.scss +1 -0
  229. package/styles/recurrence-editor/_fabric-dark-definition.scss +1 -0
  230. package/styles/recurrence-editor/_fabric-definition.scss +1 -0
  231. package/styles/recurrence-editor/_fluent-definition.scss +1 -0
  232. package/styles/recurrence-editor/_fluent2-definition.scss +1 -0
  233. package/styles/recurrence-editor/_fusionnew-definition.scss +1 -0
  234. package/styles/recurrence-editor/_highcontrast-definition.scss +1 -0
  235. package/styles/recurrence-editor/_highcontrast-light-definition.scss +1 -0
  236. package/styles/recurrence-editor/_layout.scss +5 -1
  237. package/styles/recurrence-editor/_material-dark-definition.scss +1 -0
  238. package/styles/recurrence-editor/_material-definition.scss +1 -0
  239. package/styles/recurrence-editor/_material3-definition.scss +1 -0
  240. package/styles/recurrence-editor/_tailwind-definition.scss +1 -0
  241. package/styles/recurrence-editor/_tailwind3-definition.scss +1 -0
  242. package/styles/recurrence-editor/bds.css +3 -0
  243. package/styles/recurrence-editor/bootstrap-dark.css +4 -1
  244. package/styles/recurrence-editor/bootstrap.css +4 -1
  245. package/styles/recurrence-editor/bootstrap4.css +3 -0
  246. package/styles/recurrence-editor/bootstrap5-dark.css +3 -0
  247. package/styles/recurrence-editor/bootstrap5.3.css +3 -0
  248. package/styles/recurrence-editor/bootstrap5.css +3 -0
  249. package/styles/recurrence-editor/fabric-dark.css +4 -1
  250. package/styles/recurrence-editor/fabric.css +4 -1
  251. package/styles/recurrence-editor/fluent-dark.css +4 -1
  252. package/styles/recurrence-editor/fluent.css +4 -1
  253. package/styles/recurrence-editor/fluent2.css +3 -0
  254. package/styles/recurrence-editor/highcontrast-light.css +4 -1
  255. package/styles/recurrence-editor/highcontrast.css +4 -1
  256. package/styles/recurrence-editor/material-dark.css +4 -1
  257. package/styles/recurrence-editor/material.css +4 -1
  258. package/styles/recurrence-editor/material3-dark.css +3 -0
  259. package/styles/recurrence-editor/material3.css +3 -0
  260. package/styles/recurrence-editor/tailwind-dark.css +3 -0
  261. package/styles/recurrence-editor/tailwind.css +3 -0
  262. package/styles/recurrence-editor/tailwind3.css +3 -0
  263. package/styles/schedule/_bds-definition.scss +2 -0
  264. package/styles/schedule/_bootstrap-dark-definition.scss +2 -0
  265. package/styles/schedule/_bootstrap-definition.scss +2 -0
  266. package/styles/schedule/_bootstrap4-definition.scss +2 -0
  267. package/styles/schedule/_bootstrap5-definition.scss +2 -0
  268. package/styles/schedule/_bootstrap5.3-definition.scss +2 -0
  269. package/styles/schedule/_fabric-dark-definition.scss +2 -0
  270. package/styles/schedule/_fabric-definition.scss +2 -0
  271. package/styles/schedule/_fluent-definition.scss +3 -1
  272. package/styles/schedule/_fluent2-definition.scss +2 -0
  273. package/styles/schedule/_fusionnew-definition.scss +2 -0
  274. package/styles/schedule/_highcontrast-definition.scss +2 -0
  275. package/styles/schedule/_highcontrast-light-definition.scss +2 -0
  276. package/styles/schedule/_layout.scss +12 -11
  277. package/styles/schedule/_material-dark-definition.scss +2 -0
  278. package/styles/schedule/_material-definition.scss +2 -0
  279. package/styles/schedule/_material3-definition.scss +2 -0
  280. package/styles/schedule/_tailwind-definition.scss +2 -0
  281. package/styles/schedule/_tailwind3-definition.scss +2 -0
  282. package/styles/schedule/bds.css +8 -8
  283. package/styles/schedule/bootstrap-dark.css +8 -8
  284. package/styles/schedule/bootstrap.css +8 -8
  285. package/styles/schedule/bootstrap4.css +8 -8
  286. package/styles/schedule/bootstrap5-dark.css +8 -8
  287. package/styles/schedule/bootstrap5.3.css +8 -8
  288. package/styles/schedule/bootstrap5.css +8 -8
  289. package/styles/schedule/fabric-dark.css +8 -8
  290. package/styles/schedule/fabric.css +8 -8
  291. package/styles/schedule/fluent-dark.css +9 -9
  292. package/styles/schedule/fluent.css +9 -9
  293. package/styles/schedule/fluent2.css +8 -8
  294. package/styles/schedule/highcontrast-light.css +8 -8
  295. package/styles/schedule/highcontrast.css +8 -8
  296. package/styles/schedule/material-dark.css +8 -8
  297. package/styles/schedule/material.css +8 -8
  298. package/styles/schedule/material3-dark.css +8 -8
  299. package/styles/schedule/material3.css +8 -8
  300. package/styles/schedule/tailwind-dark.css +8 -8
  301. package/styles/schedule/tailwind.css +8 -8
  302. package/styles/schedule/tailwind3.css +8 -8
  303. package/styles/tailwind-dark-lite.css +11 -8
  304. package/styles/tailwind-dark.css +11 -8
  305. package/styles/tailwind-lite.css +11 -8
  306. package/styles/tailwind.css +11 -8
  307. package/styles/tailwind3-lite.css +11 -8
  308. package/styles/tailwind3.css +11 -8
@@ -0,0 +1,1401 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import { createElement, closest, Draggable, extend, formatUnit, isNullOrUndefined } from '@syncfusion/ej2-base';
3
+ import { addClass, remove, removeClass, setStyleAttribute } from '@syncfusion/ej2-base';
4
+ import { DragEventArgs, EventFieldsMapping, TdData, EJ2Instance } from '../base/interface';
5
+ import { ActionBase } from '../actions/action-base';
6
+ import { MonthEvent } from '../event-renderer/month';
7
+ import { TimelineEvent } from '../event-renderer/timeline-view';
8
+ import { YearEvent } from '../event-renderer/year';
9
+ import { HeaderRowsModel } from '../models/header-rows-model';
10
+ import { VerticalEvent } from '../event-renderer/vertical-view';
11
+ import * as cls from '../base/css-constant';
12
+ import * as events from '../base/constant';
13
+ import * as util from '../base/util';
14
+ import { NavigationDirection } from '../base/type';
15
+
16
+ const MINUTES_PER_DAY: number = 1440;
17
+
18
+ /**
19
+ * Schedule events drag actions
20
+ */
21
+
22
+ export class DragAndDrop extends ActionBase {
23
+ private widthUptoCursorPoint: number = 0;
24
+ private heightUptoCursorPoint: number = 0;
25
+ private timelineEventModule: TimelineEvent;
26
+ private cursorPointIndex: number = 0;
27
+ private isHeaderRows: boolean = false;
28
+ private isTimelineDayProcess: boolean = false;
29
+ private widthPerMinute: number = 0;
30
+ private heightPerMinute: number = 0;
31
+ private minDiff: number = 0;
32
+ private isStepDragging: boolean = false;
33
+ private isMorePopupOpened: boolean = false;
34
+ private isAllDayDrag: boolean = false;
35
+ private isMultiSelect: boolean = false;
36
+ private multiData: Record<string, any>[] = [];
37
+ private updatedData: Record<string, any>[] = [];
38
+ private swagData: Record<string, any>[] = [];
39
+ private startTime: number = 0;
40
+ private isAllDayTarget: boolean = false;
41
+ private targetTd: HTMLElement = null;
42
+ private isCursorAhead: boolean = false;
43
+ private dragArea: HTMLElement;
44
+ private enableCurrentViewDrag: boolean = false;
45
+ private isPreventMultiDrag: boolean = false;
46
+ private slotsUptoCursor: number = -1;
47
+ private eleTop: number = 0;
48
+ private distanceUptoCursor: number = 0;
49
+
50
+ public wireDragEvent(element: HTMLElement): void {
51
+ new Draggable(element, {
52
+ abort: '.' + cls.EVENT_RESIZE_CLASS + ', .' + cls.INLINE_EDIT_CLASS,
53
+ clone: true,
54
+ isDragScroll: true,
55
+ enableTailMode: this.parent.eventDragArea ? true : false,
56
+ cursorAt: (this.parent.eventDragArea) ? { left: -20, top: -20 } : { left: 0, top: 0 },
57
+ dragArea: this.dragArea,
58
+ dragStart: this.dragStart.bind(this),
59
+ drag: this.drag.bind(this),
60
+ dragStop: this.dragStop.bind(this),
61
+ enableAutoScroll: false,
62
+ helper: this.dragHelper.bind(this),
63
+ queryPositionInfo: this.dragPosition.bind(this)
64
+ });
65
+ }
66
+
67
+ public setDragArea(): void {
68
+ const dragElement: HTMLElement = document.querySelector(this.parent.eventDragArea);
69
+ this.dragArea = this.parent.eventDragArea && dragElement ? dragElement :
70
+ this.parent.element.querySelector('.' + cls.CONTENT_TABLE_CLASS) as HTMLElement;
71
+ }
72
+
73
+ private dragHelper(e: Record<string, any>): HTMLElement {
74
+ if (e.sender && e.sender.type === 'touchmove' && (!this.parent.uiStateValues.isTapHold ||
75
+ !e.element.classList.contains(cls.APPOINTMENT_BORDER))) {
76
+ return null;
77
+ }
78
+ this.setDragActionDefaultValues();
79
+ this.actionObj.element = e.element as HTMLElement;
80
+ if (e.sender && ['Day', 'Week', 'WorkWeek'].indexOf(this.parent.currentView) > -1) {
81
+ const eventArgs: (MouseEvent & TouchEvent) | Touch = this.parent.eventBase.getPageCoordinates(e.sender);
82
+ this.distanceUptoCursor = eventArgs.clientY - this.actionObj.element.getBoundingClientRect().top;
83
+ this.eleTop = parseFloat(this.actionObj.element.style.top);
84
+ this.slotsUptoCursor = -1;
85
+ }
86
+ this.actionObj.action = 'drag';
87
+ let elements: Element[] = [];
88
+ if (!this.parent.allowMultiDrag || isNullOrUndefined(this.parent.selectedElements) || this.parent.selectedElements.length === 0 ||
89
+ (this.parent.selectedElements.length > 0 && this.parent.selectedElements.indexOf(this.actionObj.element) === -1)) {
90
+ elements = [e.element as HTMLElement];
91
+ } else {
92
+ elements = this.parent.selectedElements;
93
+ this.isMultiSelect = true;
94
+ }
95
+ elements.forEach((ele: HTMLElement) => {
96
+ const cloneElement: HTMLElement = this.createCloneElement(ele);
97
+ if (ele.getAttribute('data-guid') === this.actionObj.element.getAttribute('data-guid')) {
98
+ this.actionObj.clone = cloneElement;
99
+ if (!this.parent.eventDragArea && this.parent.currentView !== 'Month' &&
100
+ this.parent.activeViewOptions.timeScale.enable && !this.parent.activeView.isTimelineView() &&
101
+ !this.actionObj.element.classList.contains(cls.ALLDAY_APPOINTMENT_CLASS)) {
102
+ setStyleAttribute(this.actionObj.clone, { cursor: 'move', left: '0%', right: '0%', width: '100%' });
103
+ }
104
+ this.actionObj.clone.style.top = formatUnit(this.actionObj.element.offsetTop);
105
+ }
106
+ this.actionObj.cloneElement.push(cloneElement);
107
+ this.actionObj.originalElement.push(ele);
108
+ });
109
+ return this.actionObj.clone;
110
+ }
111
+
112
+ private dragPosition(e: Record<string, any>): Record<string, any> {
113
+ if (this.parent.eventDragArea) {
114
+ return { left: e.left, top: e.top };
115
+ }
116
+ const cellHeight: number = (this.actionObj.cellHeight / this.actionObj.slotInterval) * this.actionObj.interval;
117
+ let leftValue: string = formatUnit(0);
118
+ if (this.parent.currentView === 'Month') {
119
+ leftValue = e.left as string;
120
+ }
121
+ let cloneRight: number;
122
+ if (this.isStepDragging) {
123
+ cloneRight = Math.ceil(this.actionObj.clone.getBoundingClientRect().right) + this.actionObj.interval;
124
+ } else {
125
+ cloneRight = this.actionObj.clone.getBoundingClientRect().right;
126
+ }
127
+ const dragArea: HTMLElement = this.parent.element.querySelector('.' + cls.CONTENT_WRAP_CLASS) as HTMLElement;
128
+ const contentWrapRight: number = dragArea.getBoundingClientRect().right;
129
+ if (this.parent.activeView.isTimelineView() && this.parent.currentView !== 'TimelineYear' && !this.parent.enableRtl &&
130
+ this.actionObj.pageX > cloneRight && !this.isMorePopupOpened && !(this.actionObj.pageX > contentWrapRight)) {
131
+ this.isCursorAhead = true;
132
+ }
133
+ if (this.parent.activeView.isTimelineView()) {
134
+ leftValue = formatUnit(this.actionObj.clone.offsetLeft);
135
+ }
136
+ let topValue: string;
137
+ if ((this.parent.activeView.isTimelineView() || !this.parent.timeScale.enable ||
138
+ (!isNullOrUndefined(this.actionObj.clone.offsetParent) &&
139
+ this.actionObj.clone.offsetParent.classList.contains(cls.MORE_EVENT_POPUP_CLASS)))) {
140
+ topValue = formatUnit(this.actionObj.clone.offsetTop);
141
+ } else if (this.parent.currentView === 'Month') {
142
+ topValue = formatUnit(0);
143
+ } else if (this.actionObj.clone.classList.contains(cls.ALLDAY_APPOINTMENT_CLASS)) {
144
+ topValue = formatUnit((<HTMLElement>this.parent.element.querySelector('.' + cls.ALLDAY_ROW_CLASS)).offsetTop);
145
+ setStyleAttribute(this.actionObj.clone, {
146
+ width: formatUnit(Math.ceil(this.actionObj.clone.offsetWidth / this.actionObj.cellWidth) * this.actionObj.cellWidth),
147
+ right: this.parent.enableRtl && formatUnit(0)
148
+ });
149
+ } else {
150
+ if (this.actionObj.element.classList.contains(cls.ALLDAY_APPOINTMENT_CLASS) &&
151
+ !this.actionObj.clone.classList.contains(cls.ALLDAY_APPOINTMENT_CLASS)) {
152
+ setStyleAttribute(this.actionObj.clone, {
153
+ height: formatUnit(this.actionObj.cellHeight),
154
+ width: formatUnit(this.actionObj.cellWidth - 1),
155
+ pointerEvents: 'none'
156
+ });
157
+ }
158
+ let top: number = parseInt(<string>e.top, 10);
159
+ top = top < 0 ? 0 : top;
160
+ if (this.slotsUptoCursor < 0) {
161
+ const cellsCountUptoCursor: number = Math.floor((this.eleTop + this.distanceUptoCursor) / cellHeight);
162
+ const cellsCountUptoEleTop: number = Math.floor(this.eleTop / cellHeight);
163
+ this.slotsUptoCursor = cellsCountUptoCursor - cellsCountUptoEleTop;
164
+ }
165
+ top = (Math.floor((top + this.distanceUptoCursor + 1) / cellHeight) - this.slotsUptoCursor) * cellHeight;
166
+ topValue = formatUnit(top < 0 ? 0 : top);
167
+ const scrollHeight: number = this.parent.element.querySelector('.e-content-wrap').scrollHeight;
168
+ const cloneBottom: number = parseInt(topValue, 10) + this.actionObj.clone.offsetHeight;
169
+ if (cloneBottom > scrollHeight) {
170
+ topValue = (parseInt(topValue, 10) - (cloneBottom - scrollHeight)) + 'px';
171
+ }
172
+ if (this.isPreventMultiDrag) {
173
+ topValue = formatUnit(this.actionObj.clone.offsetTop);
174
+ }
175
+ }
176
+ return { left: leftValue, top: topValue };
177
+ }
178
+
179
+ private setDragActionDefaultValues(): void {
180
+ this.actionObj.action = 'drag';
181
+ this.actionObj.isAllDay = null;
182
+ this.actionObj.slotInterval = this.parent.activeViewOptions.timeScale.interval / this.parent.activeViewOptions.timeScale.slotCount;
183
+ this.actionObj.interval = this.actionObj.slotInterval;
184
+ const workCell: HTMLElement = this.parent.element.querySelector('.' + cls.WORK_CELLS_CLASS) as HTMLElement;
185
+ this.actionObj.cellWidth = workCell.offsetWidth;
186
+ this.actionObj.cellHeight = workCell.offsetHeight;
187
+ }
188
+
189
+ private dragStart(e: MouseEvent & TouchEvent & DragEventArgs): void {
190
+ const eventGuid: string = this.actionObj.element.getAttribute('data-guid');
191
+ this.actionObj.event = this.parent.eventBase.getEventByGuid(eventGuid) as Record<string, any>;
192
+ const eventObj: Record<string, any> = extend({}, this.actionObj.event, null, true) as Record<string, any>;
193
+ if (!isNullOrUndefined(eventObj)) {
194
+ this.startTime = (eventObj[this.parent.eventFields.startTime] as Date).getTime();
195
+ }
196
+ if (!this.parent.allowMultiDrag) {
197
+ this.parent.eventBase.removeSelectedAppointmentClass();
198
+ }
199
+ const dragArgs: DragEventArgs = {
200
+ cancel: false,
201
+ data: eventObj,
202
+ selectedData: this.getSelectedData(),
203
+ event: e,
204
+ excludeSelectors: null,
205
+ element: this.actionObj.element,
206
+ interval: this.actionObj.interval,
207
+ navigation: { enable: false, timeDelay: 2000 },
208
+ scroll: { enable: true, scrollBy: 30, timeDelay: 100 }
209
+ };
210
+ this.parent.trigger(events.dragStart, dragArgs, (dragEventArgs: DragEventArgs) => {
211
+ if (dragEventArgs.cancel || (!isNullOrUndefined(this.actionObj.element) &&
212
+ isNullOrUndefined(this.actionObj.element.parentElement))) {
213
+ const dragObj: Draggable = (this.actionObj.element as EJ2Instance).ej2_instances[0] as Draggable;
214
+ if (!isNullOrUndefined(dragObj)) {
215
+ dragObj.intDestroy((e as DragEventArgs).event as MouseEvent & TouchEvent);
216
+ }
217
+ this.isMultiSelect = false;
218
+ this.multiData = [];
219
+ this.actionObj.action = '';
220
+ this.removeCloneElementClasses();
221
+ this.removeCloneElement();
222
+ return;
223
+ }
224
+ this.actionClass('addClass');
225
+ this.parent.uiStateValues.action = true;
226
+ this.actionObj.start = eventObj[this.parent.eventFields.startTime] as Date;
227
+ this.actionObj.end = eventObj[this.parent.eventFields.endTime] as Date;
228
+ this.actionObj.groupIndex = parseInt(this.actionObj.element.getAttribute('data-group-index') || '0', 10);
229
+ this.actionObj.interval = dragEventArgs.interval;
230
+ this.actionObj.navigation = dragEventArgs.navigation;
231
+ this.actionObj.scroll = dragEventArgs.scroll;
232
+ this.enableCurrentViewDrag = dragArgs.dragWithinRange && !dragArgs.navigation.enable && this.parent.allowMultiDrag;
233
+ this.actionObj.excludeSelectors = dragEventArgs.excludeSelectors;
234
+ const viewElement: HTMLElement = this.parent.element.querySelector('.' + cls.CONTENT_WRAP_CLASS) as HTMLElement;
235
+ this.scrollArgs = { element: viewElement, width: viewElement.scrollWidth, height: viewElement.scrollHeight };
236
+ this.widthPerMinute = (this.actionObj.cellWidth / this.actionObj.slotInterval) * this.actionObj.interval;
237
+ this.heightPerMinute = (this.actionObj.cellHeight / this.actionObj.slotInterval) * this.actionObj.interval;
238
+ this.widthUptoCursorPoint = 0;
239
+ this.heightUptoCursorPoint = 0;
240
+ this.cursorPointIndex = -1;
241
+ this.isHeaderRows = false;
242
+ this.isTimelineDayProcess = false;
243
+ this.minDiff = 0;
244
+ this.isMorePopupOpened = false;
245
+ this.daysVariation = -1;
246
+ this.isAllDayTarget = this.actionObj.clone.classList.contains(cls.ALLDAY_APPOINTMENT_CLASS);
247
+ if ((this.parent.activeView.isTimelineView() || !this.parent.timeScale.enable) && this.parent.currentView !== 'TimelineYear') {
248
+ if (!isNullOrUndefined(this.actionObj.clone.offsetParent) &&
249
+ this.actionObj.clone.offsetParent.classList.contains(cls.MORE_EVENT_POPUP_CLASS)) {
250
+ this.isMorePopupOpened = true;
251
+ }
252
+ this.actionObj.pageX = (e as DragEventArgs).event.pageX;
253
+ const rows: HeaderRowsModel[] = this.parent.activeViewOptions.headerRows;
254
+ this.isHeaderRows = rows.length > 0 && rows[rows.length - 1].option !== 'Hour' &&
255
+ rows[rows.length - 1].option !== 'Date';
256
+ this.isTimelineDayProcess = !this.parent.activeViewOptions.timeScale.enable || this.isHeaderRows ||
257
+ this.parent.currentView === 'TimelineMonth' || (rows.length > 0 && rows[rows.length - 1].option === 'Date');
258
+ this.isAllDayDrag = !this.isTimelineDayProcess && eventObj[this.parent.eventFields.isAllDay];
259
+ this.isStepDragging = !this.isTimelineDayProcess && !this.isAllDayDrag &&
260
+ (this.actionObj.slotInterval !== this.actionObj.interval);
261
+ if (this.isTimelineDayProcess) {
262
+ this.timelineEventModule = new TimelineEvent(this.parent, 'day');
263
+ } else {
264
+ this.timelineEventModule = new TimelineEvent(this.parent, 'hour');
265
+ }
266
+ }
267
+ if (this.parent.currentView === 'TimelineYear') {
268
+ this.yearEvent = new YearEvent(this.parent);
269
+ }
270
+ if (this.parent.currentView === 'Month') {
271
+ this.startTime = util.resetTime(new Date(this.startTime)).getTime();
272
+ this.updateOriginalElement(this.actionObj.clone);
273
+ this.monthEvent = new MonthEvent(this.parent);
274
+ }
275
+ if (this.parent.currentView === 'Day' || this.parent.currentView === 'Week' || this.parent.currentView === 'WorkWeek') {
276
+ this.verticalEvent = new VerticalEvent(this.parent);
277
+ this.verticalEvent.initializeValues();
278
+ const splitEvents: Record<string, any>[] = this.splitEvent(this.actionObj.event);
279
+ splitEvents.forEach((event: Record<string, any>) => {
280
+ let query: string =
281
+ `.e-day-wrapper[data-date="${(<Date>util.resetTime(event[this.parent.eventFields.startTime])).getTime()}"]`;
282
+ if (this.parent.activeViewOptions.group.resources.length > 0) {
283
+ query = query.concat('[data-group-index = "' + this.actionObj.groupIndex + '"]');
284
+ }
285
+ const appWrap: HTMLTableCellElement = this.parent.element.querySelector(query) as HTMLTableCellElement;
286
+ if (appWrap) {
287
+ const appEle: Element = appWrap.querySelector('[data-id="' + this.actionObj.clone.getAttribute('data-id') + '"]');
288
+ if (appEle) {
289
+ addClass([appEle], cls.EVENT_ACTION_CLASS);
290
+ }
291
+ }
292
+ });
293
+ }
294
+ });
295
+ }
296
+
297
+ public getSelectedData(): Record<string, any>[] {
298
+ if (this.isMultiSelect && this.multiData.length === 0 && this.parent.selectedElements.length > 0) {
299
+ for (const element of this.parent.selectedElements) {
300
+ const eventGuid: string = element.getAttribute('data-guid');
301
+ const data: Record<string, any> = this.parent.eventBase.getEventByGuid(eventGuid) as Record<string, any>;
302
+ this.multiData.push(extend({}, data, null, true) as Record<string, any>);
303
+ }
304
+ }
305
+ return this.multiData;
306
+ }
307
+
308
+ private drag(e: MouseEvent & TouchEvent): void {
309
+ if ((e as Record<string, any>).event && (e as Record<string, any>).event.type === 'touchmove') {
310
+ (e as Record<string, any>).event.preventDefault();
311
+ }
312
+ if (this.parent.quickPopup) {
313
+ this.parent.quickPopup.quickPopupHide(true);
314
+ }
315
+ if ((!isNullOrUndefined(e.target)) && (e.target as HTMLElement).classList &&
316
+ (e.target as HTMLElement).classList.contains(cls.DISABLE_DATES)) {
317
+ return;
318
+ }
319
+ const eventObj: Record<string, any> = extend({}, this.actionObj.event, null, true) as Record<string, any>;
320
+ const eventArgs: (MouseEvent & TouchEvent) | Touch = this.parent.eventBase.getPageCoordinates(e);
321
+ this.actionObj.Y = this.actionObj.pageY = eventArgs.pageY;
322
+ this.actionObj.X = this.actionObj.pageX = eventArgs.pageX;
323
+ this.actionObj.target = e.target;
324
+ this.widthUptoCursorPoint = (this.widthUptoCursorPoint === 0) ?
325
+ Math.ceil((Math.abs(this.actionObj.clone.getBoundingClientRect().left - this.actionObj.X) / this.widthPerMinute)) *
326
+ this.widthPerMinute : this.widthUptoCursorPoint;
327
+ this.widthUptoCursorPoint = this.isMorePopupOpened ? this.actionObj.cellWidth : this.widthUptoCursorPoint;
328
+ this.heightUptoCursorPoint = (this.heightUptoCursorPoint === 0) ?
329
+ Math.ceil((Math.abs(this.actionObj.clone.getBoundingClientRect().top - this.actionObj.Y) / this.heightPerMinute)) *
330
+ this.heightPerMinute : this.heightUptoCursorPoint;
331
+ if (['Day', 'Week', 'WorkWeek'].indexOf(this.parent.currentView) > -1) {
332
+ this.isAllDayDrag = (this.parent.activeViewOptions.timeScale.enable) ?
333
+ this.actionObj.clone.classList.contains(cls.ALLDAY_APPOINTMENT_CLASS) :
334
+ this.actionObj.event[this.parent.eventFields.isAllDay] as boolean;
335
+ }
336
+ if (this.isStepDragging && this.minDiff === 0) {
337
+ this.calculateMinutesDiff(eventObj);
338
+ }
339
+ if ((this.parent.currentView === 'Month' || this.isAllDayDrag) && this.daysVariation < 0) {
340
+ const date: Date = this.parent.getDateFromElement(this.actionObj.target as HTMLElement);
341
+ if (!isNullOrUndefined(date)) {
342
+ const currentDate: Date = util.resetTime(date);
343
+ const startDate: Date = util.resetTime(new Date((eventObj[this.parent.eventFields.startTime] as Date).getTime()));
344
+ this.daysVariation = (currentDate.getTime() - startDate.getTime()) / util.MS_PER_DAY;
345
+ } else {
346
+ this.daysVariation = 0;
347
+ }
348
+ } else {
349
+ this.daysVariation = 0;
350
+ }
351
+ if (this.parent.eventDragArea) {
352
+ const targetElement: HTMLElement = eventArgs.target as HTMLElement;
353
+ this.actionObj.clone.style.top = formatUnit(targetElement.offsetTop);
354
+ this.actionObj.clone.style.left = formatUnit(targetElement.offsetLeft);
355
+ const currentTarget: Element = <Element>closest(targetElement, '.' + cls.ROOT);
356
+ if (!currentTarget) {
357
+ this.actionObj.clone.style.height = '';
358
+ this.actionObj.clone.style.width = '';
359
+ } else {
360
+ if (!(this.parent.currentView === 'Week' || this.parent.currentView === 'WorkWeek' || this.parent.currentView === 'Day')) {
361
+ this.actionObj.clone.style.width = formatUnit(this.actionObj.element.offsetWidth);
362
+ }
363
+ }
364
+ }
365
+ this.updateScrollPosition(e);
366
+ this.updateNavigatingPosition(e);
367
+ this.updateDraggingDateTime(e);
368
+ const dragArgs: DragEventArgs = {
369
+ data: eventObj, event: e, element: this.actionObj.element, startTime: this.actionObj.start,
370
+ endTime: this.actionObj.end, selectedData: this.updatedData
371
+ };
372
+ if (this.parent.group.resources.length > 0) {
373
+ dragArgs.groupIndex = this.actionObj.groupIndex;
374
+ }
375
+ this.parent.trigger(events.drag, dragArgs);
376
+ }
377
+
378
+ private calculateMinutesDiff(eventObj: Record<string, any>): void {
379
+ if (this.parent.enableRtl) {
380
+ this.minDiff =
381
+ ((this.actionObj.clone.offsetWidth - this.widthUptoCursorPoint) / this.widthPerMinute) * this.actionObj.interval;
382
+ } else {
383
+ this.minDiff = (this.widthUptoCursorPoint / this.widthPerMinute) * this.actionObj.interval;
384
+ }
385
+ const startDate: Date = eventObj[this.parent.eventFields.startTime] as Date;
386
+ const startTime: Date = this.parent.activeView.renderDates[0];
387
+ const startEndHours: { [key: string]: Date } =
388
+ util.getStartEndHours(startTime, this.parent.activeView.getStartHour(), this.parent.activeView.getEndHour());
389
+ if (startEndHours.startHour.getTime() > startDate.getTime()) {
390
+ this.minDiff = this.minDiff + ((startEndHours.startHour.getTime() - startDate.getTime()) / util.MS_PER_MINUTE);
391
+ }
392
+ }
393
+
394
+ private dragStop(e: MouseEvent): void {
395
+ this.isCursorAhead = false;
396
+ this.isPreventMultiDrag = false;
397
+ this.removeCloneElementClasses();
398
+ this.removeCloneElement();
399
+ clearInterval(this.actionObj.navigationInterval);
400
+ this.actionObj.navigationInterval = null;
401
+ clearInterval(this.actionObj.scrollInterval);
402
+ this.actionObj.scrollInterval = null;
403
+ this.actionClass('removeClass');
404
+ this.parent.uiStateValues.action = this.parent.uiStateValues.isTapHold = false;
405
+ if (this.isAllowDrop(e)) {
406
+ return;
407
+ }
408
+ const target: HTMLElement = ((e.target as Element).classList && (!(e.target as Element).classList.contains('e-work-cells') && this.parent.cellTemplate) ?
409
+ closest(e.target as Element, '.e-work-cells') : e.target) as HTMLElement;
410
+ const dragArgs: DragEventArgs = {
411
+ cancel: false, data: this.getChangedData(this.updatedData), selectedData: this.updatedData,
412
+ event: e, element: this.actionObj.element, target: target
413
+ };
414
+ this.actionObj.action = null;
415
+ this.parent.trigger(events.dragStop, dragArgs, (dragEventArgs: DragEventArgs) => {
416
+ if (dragEventArgs.cancel) {
417
+ return;
418
+ }
419
+ if (this.parent.eventBase.checkOverlap(dragEventArgs.data)) {
420
+ return;
421
+ }
422
+ if (this.parent.isSpecificResourceEvents()) {
423
+ this.parent.crudModule.crudObj.isCrudAction = true;
424
+ this.parent.crudModule.crudObj.sourceEvent =
425
+ [this.parent.resourceBase.lastResourceLevel[parseInt(dragArgs.element.getAttribute('data-group-index'), 10)]];
426
+ const currentGroupIndex: number = parseInt(dragArgs.target.getAttribute('data-group-index'), 10) || this.actionObj.groupIndex;
427
+ this.parent.crudModule.crudObj.targetEvent =
428
+ [this.parent.resourceBase.lastResourceLevel[parseInt(currentGroupIndex.toString(), 10)]];
429
+ }
430
+ this.saveChangedData(dragEventArgs, this.isMultiSelect);
431
+ });
432
+ this.updatedData = [];
433
+ this.multiData = [];
434
+ this.isMultiSelect = false;
435
+ this.parent.selectedElements = [];
436
+ }
437
+
438
+ public updateNavigatingPosition(e: MouseEvent & TouchEvent): void {
439
+ if (this.actionObj.navigation.enable) {
440
+ let currentDate: Date = this.parent.getCurrentTime();
441
+ if (isNullOrUndefined(this.actionObj.navigationInterval)) {
442
+ this.actionObj.navigationInterval = window.setInterval(
443
+ () => {
444
+ if (currentDate) {
445
+ const crtDate: Date = this.parent.getCurrentTime();
446
+ const end: number = crtDate.getSeconds();
447
+ let start: number = currentDate.getSeconds() + (this.actionObj.navigation.timeDelay / 1000);
448
+ start = (start >= 60) ? start - 60 : start;
449
+ if (start === end) {
450
+ currentDate = this.parent.getCurrentTime();
451
+ this.viewNavigation(e);
452
+ this.updateDraggingDateTime(e);
453
+ }
454
+ }
455
+ },
456
+ this.actionObj.navigation.timeDelay);
457
+ }
458
+ }
459
+ }
460
+
461
+ public updateDraggingDateTime(e: MouseEvent & TouchEvent): void {
462
+ if (!isNullOrUndefined(this.actionObj.clone.offsetParent) &&
463
+ this.actionObj.clone.offsetParent.classList.contains(cls.MORE_EVENT_POPUP_CLASS)) {
464
+ this.morePopupEventDragging(e);
465
+ } else if (this.parent.activeView.isTimelineView() && this.parent.currentView !== 'TimelineYear') {
466
+ this.timelineEventModule.dateRender = this.parent.activeView.renderDates;
467
+ this.timelineEventModule.cellWidth = this.actionObj.cellWidth;
468
+ this.timelineEventModule.getSlotDates();
469
+ this.actionObj.cellWidth = this.isHeaderRows ? this.timelineEventModule.cellWidth :
470
+ this.parent.getElementWidth(this.parent.element.querySelector('.' + cls.WORK_CELLS_CLASS));
471
+ this.calculateTimelineTime(e);
472
+ } else {
473
+ if (this.parent.currentView === 'Month' || this.parent.currentView === 'TimelineYear') {
474
+ this.calculateVerticalDate(e);
475
+ } else {
476
+ this.calculateVerticalTime(e);
477
+ }
478
+ }
479
+ }
480
+
481
+ public navigationWrapper(): void {
482
+ if (!this.parent.activeView.isTimelineView()) {
483
+ if (this.parent.currentView === 'Month' || !this.parent.timeScale.enable) {
484
+ const outerWrapperCls: HTMLElement[] = [].slice.call(this.parent.element.querySelectorAll('.' + cls.WORK_CELLS_CLASS));
485
+ this.actionObj.index = (this.parent.activeView.renderDates.length < this.actionObj.index) ?
486
+ this.parent.activeView.renderDates.length - 1 : this.actionObj.index;
487
+ let targetWrapper: Element = outerWrapperCls[this.actionObj.index].querySelector('.' + cls.APPOINTMENT_WRAPPER_CLASS);
488
+ if (!targetWrapper) {
489
+ targetWrapper = createElement('div', { className: cls.APPOINTMENT_WRAPPER_CLASS });
490
+ outerWrapperCls[this.actionObj.index].appendChild(targetWrapper);
491
+ }
492
+ targetWrapper.appendChild(this.actionObj.clone);
493
+ } else {
494
+ const wrapperClass: string = this.actionObj.clone.classList.contains(cls.ALLDAY_APPOINTMENT_CLASS) ?
495
+ '.' + cls.ALLDAY_APPOINTMENT_WRAPPER_CLASS : '.' + cls.APPOINTMENT_WRAPPER_CLASS;
496
+ this.parent.element.querySelectorAll(wrapperClass)
497
+ .item(this.actionObj.index).appendChild(this.actionObj.clone);
498
+ if (wrapperClass === '.' + cls.ALLDAY_APPOINTMENT_WRAPPER_CLASS) {
499
+ const elementHeight: number = this.getAllDayEventHeight();
500
+ const event: HTMLElement[] =
501
+ [].slice.call(this.parent.element.querySelectorAll('.' + cls.ALLDAY_CELLS_CLASS + ':first-child'));
502
+ if (event[0].offsetHeight < elementHeight) {
503
+ for (const e of event) {
504
+ e.style.height = ((elementHeight + 2) / 12) + 'em';
505
+ }
506
+ }
507
+ this.actionObj.clone.style.height = formatUnit(elementHeight);
508
+ }
509
+ this.actionObj.height = parseInt(this.actionObj.clone.style.height, 10);
510
+ }
511
+ } else {
512
+ let outWrapper: Element;
513
+ if (this.parent.activeViewOptions.group.resources.length > 0) {
514
+ outWrapper = this.parent.element.querySelectorAll('.e-appointment-container:not(.e-hidden)').item(this.actionObj.index);
515
+ } else {
516
+ outWrapper = this.parent.element.querySelector('.' + cls.APPOINTMENT_CONTAINER_CLASS);
517
+ }
518
+ if (!isNullOrUndefined(outWrapper)) {
519
+ let tarWrapper: Element = outWrapper.querySelector('.' + cls.APPOINTMENT_WRAPPER_CLASS);
520
+ if (!tarWrapper) {
521
+ tarWrapper = createElement('div', { className: cls.APPOINTMENT_WRAPPER_CLASS });
522
+ outWrapper.appendChild(tarWrapper);
523
+ }
524
+ this.actionObj.cloneElement.forEach((ele: HTMLElement) => {
525
+ tarWrapper.appendChild(ele);
526
+ });
527
+ }
528
+ }
529
+ }
530
+
531
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
532
+ private viewNavigation(e: MouseEvent & TouchEvent): void {
533
+ let navigationType: NavigationDirection;
534
+ const dragArea: HTMLElement = this.parent.element.querySelector('.' + cls.CONTENT_WRAP_CLASS) as HTMLElement;
535
+ if (dragArea && ((!this.scrollEdges.top && !this.scrollEdges.bottom) ||
536
+ closest(this.actionObj.clone, '.' + cls.ALLDAY_APPOINTMENT_WRAPPER_CLASS))) {
537
+ if ((dragArea.scrollLeft === 0) &&
538
+ (Math.round(this.actionObj.X) <=
539
+ Math.round(dragArea.getBoundingClientRect().left + this.actionObj.cellWidth + window.pageXOffset))) {
540
+ navigationType = this.parent.enableRtl ? 'Next' : 'Previous';
541
+ } else if ((Math.round(dragArea.scrollLeft) + dragArea.clientWidth === dragArea.scrollWidth) &&
542
+ (Math.round(this.actionObj.X) >=
543
+ Math.round(dragArea.getBoundingClientRect().right - this.actionObj.cellWidth + window.pageXOffset))) {
544
+ navigationType = this.parent.enableRtl ? 'Previous' : 'Next';
545
+ }
546
+ if (navigationType) {
547
+ this.parent.changeDate(this.parent.activeView.getNextPreviousDate(navigationType));
548
+ }
549
+ }
550
+ }
551
+
552
+ private morePopupEventDragging(e: MouseEvent & TouchEvent): void {
553
+ if (isNullOrUndefined(e.target) || (e.target && isNullOrUndefined(closest((<HTMLTableCellElement>e.target), 'td')))) {
554
+ return;
555
+ }
556
+ const eventObj: Record<string, any> = extend({}, this.actionObj.event, null, true) as Record<string, any>;
557
+ const eventDuration: number = (<Date>eventObj[this.parent.eventFields.endTime]).getTime() -
558
+ (<Date>eventObj[this.parent.eventFields.startTime]).getTime();
559
+ const td: HTMLElement = closest((<HTMLTableCellElement>e.target), 'td') as HTMLElement;
560
+ if (this.parent.currentView === 'TimelineYear' && (!td.classList.contains(cls.WORK_CELLS_CLASS) || td.classList.contains(cls.OTHERMONTH_CLASS))) {
561
+ return;
562
+ }
563
+ const dragStart: Date = this.parent.getDateFromElement(td);
564
+ const dragEnd: Date = new Date(dragStart.getTime());
565
+ dragEnd.setMilliseconds(eventDuration);
566
+ if (this.parent.activeViewOptions.group.resources.length > 0) {
567
+ this.actionObj.groupIndex = parseInt(td.getAttribute('data-group-index'), 10);
568
+ }
569
+ this.actionObj.start = new Date(dragStart.getTime());
570
+ this.actionObj.end = new Date(dragEnd.getTime());
571
+ this.actionObj.clone.style.top = formatUnit((<HTMLElement>td.offsetParent).offsetTop);
572
+ this.actionObj.clone.style.left = formatUnit(td.offsetLeft);
573
+ this.actionObj.clone.style.width = formatUnit(td.offsetWidth);
574
+ if (this.actionObj.cloneElement.length > 1) {
575
+ this.actionObj.cloneElement.forEach((element: HTMLElement) => {
576
+ element.style.width = formatUnit(td.offsetWidth);
577
+ });
578
+ }
579
+ let eventContainer: HTMLElement = td as HTMLElement;
580
+ let eventWrapper: HTMLElement;
581
+ if (this.parent.activeView.isTimelineView()) {
582
+ const rowIndex: number = (closest(td, 'tr') as HTMLTableRowElement).rowIndex;
583
+ eventContainer = this.parent.element.querySelectorAll('.e-appointment-container').item(rowIndex) as HTMLElement;
584
+ }
585
+ eventWrapper = eventContainer.querySelector('.' + cls.APPOINTMENT_WRAPPER_CLASS) as HTMLElement;
586
+ if (!eventWrapper) {
587
+ eventWrapper = createElement('div', { className: cls.APPOINTMENT_WRAPPER_CLASS });
588
+ eventContainer.appendChild(eventWrapper);
589
+ }
590
+ this.appendCloneElement(eventWrapper);
591
+ }
592
+
593
+ private calculateVerticalTime(e: MouseEvent & TouchEvent): void {
594
+ if (isNullOrUndefined(this.actionObj.target) ||
595
+ (this.actionObj.target && isNullOrUndefined(closest((<HTMLTableCellElement>this.actionObj.target), 'tr'))) ||
596
+ (!isNullOrUndefined(closest(this.actionObj.target as Element, 'td')) && !(closest(this.actionObj.target as Element, 'td').classList.contains(cls.WORK_CELLS_CLASS)) &&
597
+ !(closest(this.actionObj.target as Element, 'td').classList.contains(cls.ALLDAY_CELLS_CLASS)))) {
598
+ return;
599
+ }
600
+ if (this.parent.activeViewOptions.timeScale.enable) {
601
+ this.swapDragging(e);
602
+ }
603
+ const dragArea: HTMLElement = this.parent.element.querySelector('.' + cls.CONTENT_WRAP_CLASS) as HTMLElement;
604
+ const eventObj: Record<string, any> = extend({}, this.actionObj.event, null, true) as Record<string, any>;
605
+ const eventStart: Date = eventObj[this.parent.eventFields.startTime] as Date;
606
+ const eventEnd: Date = eventObj[this.parent.eventFields.endTime] as Date;
607
+ const eventDuration: number = util.getUniversalTime(eventEnd) - util.getUniversalTime(eventStart);
608
+ let offsetTop: number = Math.floor(parseInt(this.actionObj.clone.style.top, 10) / this.actionObj.cellHeight)
609
+ * this.actionObj.cellHeight;
610
+ offsetTop = offsetTop < 0 ? 0 : offsetTop;
611
+ if (this.scrollEdges.top || this.scrollEdges.bottom) {
612
+ offsetTop = this.scrollEdges.top ? dragArea.scrollTop - this.heightUptoCursorPoint +
613
+ this.actionObj.cellHeight + window.pageYOffset :
614
+ (dragArea.scrollTop + dragArea.offsetHeight - this.actionObj.clone.offsetHeight + window.pageYOffset) +
615
+ (this.actionObj.clone.offsetHeight - this.heightUptoCursorPoint);
616
+ offsetTop = Math.round(offsetTop / this.actionObj.cellHeight) * this.actionObj.cellHeight;
617
+ if (dragArea.scrollTop > 0 && offsetTop < dragArea.scrollHeight) {
618
+ this.actionObj.clone.style.top = formatUnit(offsetTop);
619
+ }
620
+ }
621
+ const rowIndex: number = (this.parent.activeViewOptions.timeScale.enable) ? (offsetTop / this.actionObj.cellHeight) : 0;
622
+ const heightPerMinute: number = this.actionObj.cellHeight / this.actionObj.slotInterval;
623
+ const diffInMinutes: number = parseInt(this.actionObj.clone.style.top, 10) - offsetTop;
624
+ let tr: HTMLElement;
625
+ if (this.isAllDayDrag) {
626
+ tr = this.parent.element.querySelector('.' + cls.ALLDAY_ROW_CLASS) as HTMLElement;
627
+ } else {
628
+ const trCollections: HTMLTableRowElement[] = [].slice.call(this.parent.getContentTable().querySelectorAll('tr'));
629
+ tr = trCollections[parseInt(rowIndex.toString(), 10)] as HTMLElement;
630
+ }
631
+ let index: number;
632
+ if (!isNullOrUndefined(closest(this.actionObj.target as Element, 'td')) && (closest(this.actionObj.target as Element, 'td').classList.contains(cls.WORK_CELLS_CLASS) ||
633
+ closest(this.actionObj.target as Element, 'td').classList.contains(cls.ALLDAY_CELLS_CLASS))) {
634
+ index = (closest((<HTMLTableCellElement>this.actionObj.target), 'td') as HTMLTableCellElement).cellIndex;
635
+ }
636
+ const colIndex: number = isNullOrUndefined(index) ? (<HTMLTableCellElement>closest(this.actionObj.clone, 'td')).cellIndex : index;
637
+ this.actionObj.index = colIndex;
638
+ if (isNullOrUndefined(tr)) {
639
+ return;
640
+ }
641
+ const td: HTMLElement = tr.children[parseInt(colIndex.toString(), 10)] as HTMLElement;
642
+ if (this.parent.activeViewOptions.group.resources.length > 0 && !this.parent.uiStateValues.isGroupAdaptive) {
643
+ this.actionObj.groupIndex = parseInt(td.getAttribute('data-group-index'), 10);
644
+ }
645
+ let dragStart: Date; let dragEnd: Date;
646
+ if (this.parent.activeViewOptions.timeScale.enable && !this.isAllDayDrag) {
647
+ if (!this.enableCurrentViewDrag || this.multiData.length === 0) {
648
+ this.appendCloneElement(this.getEventWrapper(colIndex));
649
+ }
650
+ dragStart = this.parent.getDateFromElement(td);
651
+ dragStart.setMinutes(dragStart.getMinutes() + (diffInMinutes / heightPerMinute));
652
+ dragEnd = new Date(dragStart.getTime());
653
+ if (this.actionObj.element.classList.contains(cls.ALLDAY_APPOINTMENT_CLASS)) {
654
+ dragEnd.setMinutes(dragEnd.getMinutes() + this.actionObj.slotInterval);
655
+ } else {
656
+ dragEnd.setMilliseconds(eventDuration);
657
+ }
658
+ } else {
659
+ dragStart = this.parent.getDateFromElement(td);
660
+ dragStart.setDate(dragStart.getDate() - this.daysVariation);
661
+ dragStart.setHours(eventStart.getHours(), eventStart.getMinutes(), eventStart.getSeconds());
662
+ dragEnd = new Date(dragStart.getTime());
663
+ dragEnd.setMilliseconds(eventDuration);
664
+ if (!this.actionObj.element.classList.contains(cls.ALLDAY_APPOINTMENT_CLASS) &&
665
+ this.actionObj.clone.classList.contains(cls.ALLDAY_APPOINTMENT_CLASS)) {
666
+ dragEnd = util.addDays(util.resetTime(dragEnd), 1);
667
+ }
668
+ const index: number = this.parent.activeViewOptions.group.byDate || (this.parent.virtualScrollModule &&
669
+ !this.parent.activeViewOptions.timeScale.enable) ? colIndex : undefined;
670
+ this.updateAllDayEvents(dragStart, dragEnd, index);
671
+ }
672
+ this.actionObj.start = new Date(+dragStart);
673
+ this.actionObj.end = new Date(+dragEnd);
674
+ const event: Record<string, any> = this.getUpdatedEvent(this.actionObj.start, this.actionObj.end, this.actionObj.event);
675
+ const dynamicWrappers: HTMLElement[] = [].slice.call(this.parent.element.querySelectorAll('.e-dynamic-clone'));
676
+ for (const wrapper of dynamicWrappers) {
677
+ remove(wrapper);
678
+ }
679
+ if (this.multiData.length > 0) {
680
+ if (this.isAllDayTarget && this.isAllDayDrag && !isNullOrUndefined(this.actionObj.isAllDay) && !this.actionObj.isAllDay) {
681
+ const targetCellTime: number = parseInt((closest((<HTMLElement>this.actionObj.target), 'td')).getAttribute('data-date'), 10);
682
+ this.multiData.forEach((data: Record<string, any>) => {
683
+ this.swagData.push(extend({}, data, null, true) as Record<string, any>);
684
+ if (data[this.parent.eventFields.isAllDay]) {
685
+ data[this.parent.eventFields.startTime] =
686
+ new Date((data[this.parent.eventFields.startTime] as Date).getTime() + (targetCellTime - this.startTime));
687
+ const startTime: Date = new Date(data[this.parent.eventFields.startTime] as Date);
688
+ const endTime: Date = new Date(startTime.setMinutes(startTime.getMinutes() + this.actionObj.slotInterval));
689
+ data[this.parent.eventFields.endTime] = endTime;
690
+ data[this.parent.eventFields.isAllDay] = false;
691
+ }
692
+ });
693
+ this.startTime = targetCellTime;
694
+ }
695
+ if (this.isAllDayTarget && this.isAllDayDrag &&
696
+ !isNullOrUndefined(this.actionObj.isAllDay) && this.actionObj.isAllDay && this.swagData.length > 0) {
697
+ this.multiData = this.swagData;
698
+ this.swagData = [];
699
+ const eventObj: Record<string, any> = extend({}, this.actionObj.event, null, true) as Record<string, any>;
700
+ this.startTime = (eventObj[this.parent.eventFields.startTime] as Date).getTime();
701
+ }
702
+ const startTimeDiff: number = (event[this.parent.eventFields.startTime] as Date).getTime() - this.startTime;
703
+ if (this.enableCurrentViewDrag) {
704
+ const renderDates: Date[] = this.getRenderedDates();
705
+ for (let i: number = 0; i < this.multiData.length; i++) {
706
+ const eventObj: Record<string, any> =
707
+ extend({}, this.multiData[parseInt(i.toString(), 10)], null, true) as Record<string, any>;
708
+ const startTime: Date = new Date(eventObj[this.parent.eventFields.startTime].getTime() + startTimeDiff);
709
+ const dayIndex: number = this.parent.getIndexOfDate(renderDates, util.resetTime(startTime));
710
+ if (dayIndex < 0) {
711
+ this.isPreventMultiDrag = true;
712
+ break;
713
+ }
714
+ this.isPreventMultiDrag = false;
715
+ }
716
+ }
717
+ if (!this.isPreventMultiDrag) {
718
+ for (let index: number = 0; index < this.multiData.length; index++) {
719
+ this.updatedData[parseInt(index.toString(), 10)] =
720
+ this.updateMultipleData(this.multiData[parseInt(index.toString(), 10)], startTimeDiff);
721
+ const dayIndex: number = this.getDayIndex(this.updatedData[parseInt(index.toString(), 10)]);
722
+ if (dayIndex >= 0) {
723
+ const isAllDay: boolean =
724
+ this.updatedData[parseInt(index.toString(), 10)][this.parent.eventFields.isAllDay] as boolean;
725
+ const wrapper: HTMLElement = this.getEventWrapper(dayIndex, isAllDay);
726
+ this.appendCloneElement(wrapper, this.actionObj.cloneElement[parseInt(index.toString(), 10)]);
727
+ this.updateEventHeight(this.updatedData[parseInt(index.toString(), 10)], index, dayIndex);
728
+ } else {
729
+ if (!isNullOrUndefined(this.actionObj.cloneElement[parseInt(index.toString(), 10)].parentNode)) {
730
+ remove(this.actionObj.cloneElement[parseInt(index.toString(), 10)]);
731
+ }
732
+ }
733
+ }
734
+ }
735
+ } else {
736
+ this.updateEventHeight(event);
737
+ }
738
+ this.updateTimePosition(this.actionObj.start, this.updatedData);
739
+ }
740
+
741
+ private splitEvent(event: Record<string, any>): Record<string, any>[] {
742
+ const eventFields: EventFieldsMapping = this.parent.eventFields;
743
+ const eventData: Record<string, any>[] = [];
744
+ const startTime: Date = event[eventFields.startTime] as Date;
745
+ const endTime: Date = event[eventFields.endTime] as Date;
746
+ if (util.resetTime(new Date(startTime.getTime())) < util.resetTime(new Date(endTime.getTime()))) {
747
+ let startReferenceDate: Date = util.resetTime(new Date(startTime.getTime()));
748
+ let endReferenceDate: Date = new Date(startReferenceDate.getTime());
749
+ for (let i: number = 0; startReferenceDate < new Date(endTime.getTime()); i++) {
750
+ endReferenceDate = new Date(endReferenceDate.setDate(startReferenceDate.getDate() + 1));
751
+ const eventObj: Record<string, any> = extend({}, event, null, true) as Record<string, any>;
752
+ eventObj[eventFields.startTime] = new Date(startReferenceDate);
753
+ eventObj[eventFields.endTime] = new Date(endReferenceDate);
754
+ startReferenceDate = new Date(startReferenceDate.setDate(startReferenceDate.getDate() + 1));
755
+ eventData.push(eventObj);
756
+ }
757
+ const index: number = eventData.length - 1;
758
+ eventData[0][eventFields.startTime] = startTime;
759
+ eventData[parseInt(index.toString(), 10)][eventFields.endTime] = endTime;
760
+ } else {
761
+ eventData.push(event);
762
+ }
763
+ return eventData;
764
+ }
765
+
766
+ private updateMultipleData(data: Record<string, any>, timeDifference: number): Record<string, any> {
767
+ const eventObj: Record<string, any> = extend({}, data, null, true) as Record<string, any>;
768
+ if (!isNullOrUndefined(this.actionObj.isAllDay) && this.parent.activeViewOptions.timeScale.enable &&
769
+ ((this.isAllDayTarget && eventObj[this.parent.eventFields.isAllDay]) ||
770
+ (!this.isAllDayTarget && !eventObj[this.parent.eventFields.isAllDay]))) {
771
+ eventObj[this.parent.eventFields.isAllDay] = this.actionObj.isAllDay;
772
+ }
773
+ const endTimeDiff: number = (eventObj[this.parent.eventFields.endTime] as Date).getTime() -
774
+ (eventObj[this.parent.eventFields.startTime] as Date).getTime();
775
+ if (eventObj[this.parent.eventFields.isAllDay]) {
776
+ const differInDays: number = Math.ceil(timeDifference / (1000 * 3600 * 24));
777
+ const day: number = Math.ceil(endTimeDiff / (1000 * 3600 * 24));
778
+ const startTime: Date = new Date(eventObj[this.parent.eventFields.startTime] as Date);
779
+ eventObj[this.parent.eventFields.startTime] = util.resetTime(new Date(startTime.setDate(startTime.getDate() + differInDays)));
780
+ eventObj[this.parent.eventFields.endTime] = util.addDays(eventObj[this.parent.eventFields.startTime] as Date, day);
781
+ } else {
782
+ eventObj[this.parent.eventFields.startTime] =
783
+ new Date((eventObj[this.parent.eventFields.startTime] as Date).getTime() + timeDifference);
784
+ eventObj[this.parent.eventFields.endTime] =
785
+ new Date((eventObj[this.parent.eventFields.startTime] as Date).getTime() + endTimeDiff);
786
+ }
787
+ return eventObj;
788
+ }
789
+
790
+ private getDayIndex(event: Record<string, any>): number {
791
+ const eventObj: Record<string, any> = extend({}, event, null, true) as Record<string, any>;
792
+ const startDate: Date = util.resetTime(eventObj[this.parent.eventFields.startTime] as Date);
793
+ if (this.parent.activeViewOptions.timeScale.enable && !eventObj[this.parent.eventFields.isAllDay]) {
794
+ const startHour: Date = this.parent.activeView.getStartHour();
795
+ startDate.setMilliseconds(startHour.getTime() - util.resetTime(startHour).getTime());
796
+ }
797
+ const startTime: number = startDate.getTime();
798
+ let query: string = '';
799
+ let wrapper: string = cls.DAY_WRAPPER_CLASS;
800
+ if (this.parent.activeViewOptions.timeScale.enable && (eventObj[this.parent.eventFields.isAllDay])) {
801
+ wrapper = cls.ALLDAY_APPOINTMENT_WRAPPER_CLASS;
802
+ } else {
803
+ wrapper = cls.WORK_CELLS_CLASS;
804
+ }
805
+ query = '.' + wrapper + '[data-date="' + startTime + '"]';
806
+ if (this.parent.activeViewOptions.group.resources.length > 0) {
807
+ query = query + '[data-group-index="' + this.actionObj.groupIndex + '"]';
808
+ }
809
+ this.targetTd = this.parent.element.querySelector(query) as HTMLElement;
810
+ if (isNullOrUndefined(this.targetTd)) {
811
+ return -1;
812
+ }
813
+ return (this.targetTd as HTMLTableCellElement).cellIndex;
814
+ }
815
+
816
+ private updateEventHeight(event: Record<string, any>, index?: number, colIndex?: number): void {
817
+ this.verticalEvent.initializeValues();
818
+ let datesCount: number = this.verticalEvent.getStartCount();
819
+ if (!this.parent.uiStateValues.isGroupAdaptive) {
820
+ for (let i: number = 0; i < this.actionObj.groupIndex; i++) {
821
+ if (this.verticalEvent.dateRender[parseInt(i.toString(), 10)]) {
822
+ datesCount = datesCount + this.verticalEvent.dateRender[parseInt(i.toString(), 10)].length;
823
+ }
824
+ }
825
+ }
826
+ const indexGroup: number = this.parent.uiStateValues.isGroupAdaptive ? datesCount : this.actionObj.groupIndex;
827
+ const target: boolean = (this.parent.activeViewOptions.group.byDate &&
828
+ !isNullOrUndefined(this.parent.getDateFromElement(this.actionObj.target as HTMLElement))) ? true : false;
829
+ if (target || !this.parent.activeViewOptions.group.byDate) {
830
+ let dynamicIndex: number = -1;
831
+ let dayIndex: number = !this.parent.activeViewOptions.group.byDate ?
832
+ isNullOrUndefined(index) ? this.actionObj.index - datesCount : colIndex - datesCount
833
+ : this.parent.getIndexOfDate(this.verticalEvent.dateRender[parseInt(indexGroup.toString(), 10)], util.resetTime(
834
+ // eslint-disable-next-line max-len
835
+ this.parent.getDateFromElement(isNullOrUndefined(index) ? this.actionObj.target as HTMLElement : this.targetTd as HTMLElement)));
836
+ const splitEvents: Record<string, any>[] = this.splitEvent(event);
837
+ const events: Record<string, any>[] = this.parent.eventBase.isAllDayAppointment(event) || splitEvents.length > 2 ||
838
+ this.parent.eventSettings.spannedEventPlacement !== 'TimeSlot' ? [event] : splitEvents;
839
+ for (let i: number = 0; i < events.length; i++) {
840
+ if (i > 0) {
841
+ let filterQuery: string =
842
+ `.e-day-wrapper[data-date="${(<Date>util.resetTime(events[parseInt(i.toString(), 10)][this.parent.eventFields.startTime])).getTime()}"]`;
843
+ if (this.parent.activeViewOptions.group.resources.length > 0) {
844
+ filterQuery = filterQuery.concat('[data-group-index = "' + this.actionObj.groupIndex + '"]');
845
+ }
846
+ const appWrap: HTMLTableCellElement = this.parent.element.querySelector(filterQuery) as HTMLTableCellElement;
847
+ if (appWrap) {
848
+ dayIndex = dayIndex + 1;
849
+ dynamicIndex = appWrap.cellIndex;
850
+ } else {
851
+ dayIndex = -1;
852
+ }
853
+ }
854
+ if (dayIndex >= 0) {
855
+ const record: Record<string, any> =
856
+ this.verticalEvent.isSpannedEvent(events[parseInt(i.toString(), 10)], dayIndex, indexGroup);
857
+ const eStart: Date = record[this.verticalEvent.fields.startTime] as Date;
858
+ const eEnd: Date = record[this.verticalEvent.fields.endTime] as Date;
859
+ let appHeight: number = this.parent.activeViewOptions.timeScale.enable ? this.verticalEvent.getHeight(eStart, eEnd) :
860
+ this.actionObj.element.offsetHeight;
861
+ let topValue: number = this.parent.activeViewOptions.timeScale.enable ?
862
+ this.verticalEvent.getTopValue(eStart) : this.actionObj.element.offsetTop;
863
+ if (isNullOrUndefined(index)) {
864
+ if (i === 0) {
865
+ if (this.actionObj.clone.classList.contains(cls.ALLDAY_APPOINTMENT_CLASS)) {
866
+ topValue = (<HTMLElement>this.parent.element.querySelector('.' + cls.ALLDAY_ROW_CLASS)).offsetTop;
867
+ appHeight = this.getAllDayEventHeight();
868
+ }
869
+ this.actionObj.clone.style.top = formatUnit(topValue);
870
+ this.actionObj.clone.style.height = formatUnit(appHeight);
871
+ } else {
872
+ this.renderSpannedEvents(record, dynamicIndex, topValue, appHeight);
873
+ }
874
+ } else {
875
+ let appWidth: number = this.actionObj.cellWidth;
876
+ if (event[this.parent.eventFields.isAllDay] && this.parent.activeViewOptions.timeScale.enable) {
877
+ const timeDiff: number = (event[this.parent.eventFields.endTime] as Date).getTime() -
878
+ (event[this.parent.eventFields.startTime] as Date).getTime();
879
+ const allDayDifference: number = Math.ceil(timeDiff / (1000 * 3600 * 24));
880
+ if (allDayDifference >= 0) {
881
+ appWidth = (allDayDifference * this.actionObj.cellWidth);
882
+ }
883
+ }
884
+ if (this.actionObj.cloneElement[parseInt(index.toString(), 10)]) {
885
+ if (i === 0) {
886
+ this.actionObj.cloneElement[parseInt(index.toString(), 10)].style.top = formatUnit(topValue);
887
+ this.actionObj.cloneElement[parseInt(index.toString(), 10)].style.height = formatUnit(appHeight);
888
+ this.actionObj.cloneElement[parseInt(index.toString(), 10)].style.width = formatUnit(appWidth);
889
+ this.actionObj.cloneElement[parseInt(index.toString(), 10)].style.left = formatUnit(0);
890
+ } else {
891
+ this.renderSpannedEvents(record, dynamicIndex, topValue, appHeight);
892
+ }
893
+ }
894
+ }
895
+ }
896
+ }
897
+ }
898
+ }
899
+
900
+ private renderSpannedEvents(record: Record<string, any>, index: number, top: number, height: number): void {
901
+ const startTime: number = (record[this.parent.eventFields.startTime] as Date).getTime();
902
+ const endTime: number = (record[this.parent.eventFields.endTime] as Date).getTime();
903
+ if (startTime !== endTime) {
904
+ const appointmentElement: HTMLElement = this.verticalEvent.
905
+ createAppointmentElement(record, false, record.isSpanned as Record<string, any>, this.actionObj.groupIndex);
906
+ addClass([appointmentElement], [cls.CLONE_ELEMENT_CLASS, 'e-dynamic-clone']);
907
+ setStyleAttribute(appointmentElement, {
908
+ 'width': '100%',
909
+ 'height': height + 'px',
910
+ 'top': top + 'px',
911
+ 'border': '0px'
912
+ });
913
+ const appointmentWrap: HTMLElement[] =
914
+ [].slice.call(this.parent.element.querySelectorAll('.' + cls.APPOINTMENT_WRAPPER_CLASS));
915
+ appointmentWrap[parseInt(index.toString(), 10)].appendChild(appointmentElement);
916
+ }
917
+ }
918
+
919
+ private getRenderedDates(): Date[] {
920
+ let renderDates: Date[] = this.parent.activeView.renderDates;
921
+ this.parent.eventBase.slots.push(...this.parent.activeView.renderDates.map((date: Date) => +date));
922
+ if (this.parent.activeViewOptions.group.resources.length > 0) {
923
+ this.parent.eventBase.slots = [];
924
+ const resources: TdData[] = this.parent.resourceBase.lastResourceLevel.
925
+ filter((res: TdData) => res.groupIndex === this.actionObj.groupIndex);
926
+ renderDates = resources[0].renderDates;
927
+ this.parent.eventBase.slots.push(...renderDates.map((date: Date) => +date));
928
+ }
929
+ return renderDates;
930
+ }
931
+
932
+ private updateAllDayEvents(startDate: Date, endDate: Date, colIndex: number): void {
933
+ this.parent.eventBase.slots = [];
934
+ const event: Record<string, any> = this.getUpdatedEvent(startDate, endDate, this.actionObj.event);
935
+ const renderDates: Date[] = this.getRenderedDates();
936
+ const events: Record<string, any>[] = this.parent.eventBase.splitEvent(event, renderDates);
937
+ let query: string = `.e-all-day-cells[data-date="${(<Date>events[0][this.parent.eventFields.startTime]).getTime()}"]`;
938
+ if (this.parent.activeViewOptions.group.resources.length > 0 && !this.parent.uiStateValues.isGroupAdaptive) {
939
+ query = query.concat('[data-group-index = "' + this.actionObj.groupIndex + '"]');
940
+ }
941
+ const cell: HTMLElement[] = [].slice.call(this.parent.element.querySelectorAll(query));
942
+ if (cell.length > 0 || !isNullOrUndefined(colIndex)) {
943
+ const cellIndex: number = !isNullOrUndefined(colIndex) ? colIndex : (cell[0] as HTMLTableCellElement).cellIndex;
944
+ this.appendCloneElement(this.getEventWrapper(cellIndex));
945
+ // eslint-disable-next-line max-len
946
+ this.actionObj.clone.style.width = formatUnit(((<Record<string, any>>events[0].data).count as number) * this.actionObj.cellWidth);
947
+ }
948
+ }
949
+
950
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
951
+ private swapDragging(e: MouseEvent & TouchEvent): void {
952
+ if (this.isPreventMultiDrag) {
953
+ return;
954
+ }
955
+ const colIndex: number = !isNullOrUndefined(closest((<HTMLTableCellElement>this.actionObj.target), 'td')) && (closest((<HTMLTableCellElement>this.actionObj.target), 'td') as HTMLTableCellElement).cellIndex;
956
+ if (closest(this.actionObj.target as Element, '.' + cls.DATE_HEADER_WRAP_CLASS) &&
957
+ !closest(this.actionObj.clone, '.' + cls.ALLDAY_APPOINTMENT_WRAPPER_CLASS)) {
958
+ addClass([this.actionObj.clone], cls.ALLDAY_APPOINTMENT_CLASS);
959
+ this.appendCloneElement(this.getEventWrapper(colIndex));
960
+ this.actionObj.isAllDay = true;
961
+ const eventHeight: number = this.getAllDayEventHeight();
962
+ const allDayElement: HTMLElement[] =
963
+ [].slice.call(this.parent.element.querySelectorAll('.' + cls.ALLDAY_CELLS_CLASS + ':first-child'));
964
+ if (allDayElement[0].offsetHeight < eventHeight) {
965
+ for (const element of allDayElement) {
966
+ element.style.height = ((eventHeight + 2) / 12) + 'em';
967
+ }
968
+ }
969
+ setStyleAttribute(this.actionObj.clone, {
970
+ width: formatUnit(this.actionObj.cellWidth),
971
+ height: formatUnit(eventHeight),
972
+ top: formatUnit((<HTMLElement>this.parent.element.querySelector('.' + cls.ALLDAY_ROW_CLASS)).offsetTop)
973
+ });
974
+ }
975
+ if (closest(this.actionObj.target as Element, '.' + cls.WORK_CELLS_CLASS) &&
976
+ !closest(this.actionObj.clone, '.' + cls.DAY_WRAPPER_CLASS)) {
977
+ removeClass([this.actionObj.clone], cls.ALLDAY_APPOINTMENT_CLASS);
978
+ this.appendCloneElement(this.getEventWrapper(colIndex));
979
+ this.actionObj.isAllDay = false;
980
+ // eslint-disable-next-line max-len
981
+ const height: number = (this.actionObj.element.offsetHeight === 0) ? this.actionObj.height : this.actionObj.element.offsetHeight;
982
+ setStyleAttribute(this.actionObj.clone, {
983
+ left: formatUnit(0),
984
+ height: formatUnit(height),
985
+ width: formatUnit(this.actionObj.cellWidth)
986
+ });
987
+ }
988
+ }
989
+
990
+ private calculateVerticalDate(e: MouseEvent & TouchEvent): void {
991
+ if (isNullOrUndefined(e.target) || (e.target && isNullOrUndefined(closest((<HTMLTableCellElement>e.target), 'tr'))) ||
992
+ (e.target && (<HTMLTableCellElement>e.target).tagName === 'DIV')) {
993
+ return;
994
+ }
995
+ const eventObj: Record<string, any> = extend({}, this.actionObj.event, null, true) as Record<string, any>;
996
+ if (isNullOrUndefined(this.parent.eventDragArea)) {
997
+ this.removeCloneElement();
998
+ }
999
+ const eventDuration: number = util.getUniversalTime(<Date>eventObj[this.parent.eventFields.endTime]) -
1000
+ util.getUniversalTime(<Date>eventObj[this.parent.eventFields.startTime]);
1001
+ let td: HTMLTableCellElement = closest((<HTMLTableCellElement>this.actionObj.target), 'td') as HTMLTableCellElement;
1002
+ if (!isNullOrUndefined(td)) {
1003
+ const tr: HTMLTableRowElement = td.parentElement as HTMLTableRowElement;
1004
+ this.actionObj.index = (tr.rowIndex * tr.children.length) + td.cellIndex;
1005
+ const workCells: HTMLElement[] = [].slice.call(this.parent.element.querySelectorAll('.' + cls.WORK_CELLS_CLASS));
1006
+ td = <HTMLTableCellElement>workCells[this.actionObj.index];
1007
+ const currentDate: Date = this.parent.getDateFromElement(td);
1008
+ if (!isNullOrUndefined(currentDate)) {
1009
+ if (this.parent.activeViewOptions.group.resources.length > 0) {
1010
+ this.actionObj.groupIndex = parseInt(td.getAttribute('data-group-index'), 10);
1011
+ }
1012
+ const timeString: Date = new Date(currentDate.setDate(currentDate.getDate() - this.daysVariation));
1013
+ const dragStart: Date = new Date(timeString.getTime());
1014
+ const startTimeDiff: number = util.getUniversalTime(<Date>eventObj[this.parent.eventFields.startTime]) -
1015
+ util.getUniversalTime(util.resetTime(new Date(+eventObj[this.parent.eventFields.startTime])));
1016
+ dragStart.setMilliseconds(startTimeDiff);
1017
+ const dragEnd: Date = new Date(dragStart.getTime());
1018
+ dragEnd.setMilliseconds(eventDuration);
1019
+ this.actionObj.start = new Date(dragStart.getTime());
1020
+ this.actionObj.end = new Date(dragEnd.getTime());
1021
+ }
1022
+ }
1023
+ const event: Record<string, any> = this.getUpdatedEvent(this.actionObj.start, this.actionObj.end, this.actionObj.event);
1024
+ if (isNullOrUndefined(this.parent.eventDragArea)) {
1025
+ const eventWrappers: HTMLElement[] = [].slice.call(this.parent.element.querySelectorAll('.' + cls.CLONE_ELEMENT_CLASS));
1026
+ for (const wrapper of eventWrappers) {
1027
+ remove(wrapper);
1028
+ }
1029
+ }
1030
+ if (this.multiData && this.multiData.length > 0) {
1031
+ const startTime: Date = util.resetTime(new Date(event[this.parent.eventFields.startTime] as Date));
1032
+ let startTimeDiff: number = startTime.getTime() - this.startTime;
1033
+ if (this.parent.currentView === 'TimelineYear' && this.parent.group.resources.length > 0) {
1034
+ startTimeDiff = (startTime.getFullYear() - new Date(this.startTime).getFullYear()) * 12;
1035
+ startTimeDiff -= new Date(this.startTime).getMonth();
1036
+ startTimeDiff += startTime.getMonth();
1037
+ }
1038
+ for (let index: number = 0; index < this.multiData.length; index++) {
1039
+ this.updatedData[parseInt(index.toString(), 10)] =
1040
+ this.updateMultipleVerticalDate(this.multiData[parseInt(index.toString(), 10)], startTimeDiff);
1041
+ if (this.parent.currentView === 'TimelineYear') {
1042
+ this.dynamicYearlyEventsRendering(this.updatedData[parseInt(index.toString(), 10)]);
1043
+ } else {
1044
+ this.dynamicEventsRendering(this.updatedData[parseInt(index.toString(), 10)]);
1045
+ }
1046
+ }
1047
+ } else {
1048
+ if (this.parent.currentView === 'TimelineYear') {
1049
+ this.dynamicYearlyEventsRendering(event);
1050
+ } else {
1051
+ this.dynamicEventsRendering(event);
1052
+ }
1053
+ }
1054
+ }
1055
+
1056
+ private updateMultipleVerticalDate(data: Record<string, any>, timeDifference: number): Record<string, any> {
1057
+ const eventObj: Record<string, any> = extend({}, data, null, true) as Record<string, any>;
1058
+ const eventDuration: number = (<Date>eventObj[this.parent.eventFields.endTime]).getTime() -
1059
+ (<Date>eventObj[this.parent.eventFields.startTime]).getTime();
1060
+ const startDate: Date = new Date(eventObj[this.parent.eventFields.startTime] as Date);
1061
+ if (this.parent.currentView === 'TimelineYear' && this.parent.group.resources.length > 0) {
1062
+ eventObj[this.parent.eventFields.startTime] = new Date(startDate.setMonth(startDate.getMonth() + timeDifference));
1063
+ }
1064
+ else {
1065
+ const differInDays: number = Math.ceil(timeDifference / util.MS_PER_DAY);
1066
+ eventObj[this.parent.eventFields.startTime] = new Date(startDate.setDate(startDate.getDate() + differInDays));
1067
+ }
1068
+ eventObj[this.parent.eventFields.endTime] =
1069
+ new Date((eventObj[this.parent.eventFields.startTime] as Date).getTime() + eventDuration);
1070
+ return eventObj;
1071
+ }
1072
+
1073
+ private calculateTimelineTime(e: MouseEvent & TouchEvent): void {
1074
+ const eventObj: Record<string, any> = extend({}, this.actionObj.event, null, true) as Record<string, any>;
1075
+ const eventDuration: number = util.getUniversalTime(<Date>eventObj[this.parent.eventFields.endTime]) -
1076
+ util.getUniversalTime(<Date>eventObj[this.parent.eventFields.startTime]);
1077
+ let offsetLeft: number = this.parent.enableRtl ? Math.abs(this.actionObj.clone.offsetLeft) - this.actionObj.clone.offsetWidth :
1078
+ parseInt(this.actionObj.clone.style.left, 10);
1079
+ offsetLeft = Math.round(offsetLeft / this.actionObj.cellWidth) * this.actionObj.cellWidth;
1080
+ let rightOffset: number;
1081
+ if (this.parent.enableRtl) {
1082
+ rightOffset = Math.abs(parseInt(this.actionObj.clone.style.right, 10));
1083
+ this.actionObj.clone.style.right = formatUnit(rightOffset);
1084
+ }
1085
+ offsetLeft = this.getOffsetValue(offsetLeft, rightOffset);
1086
+ const colIndex: number = this.getColumnIndex(offsetLeft);
1087
+ const dragArea: HTMLElement = this.parent.element.querySelector('.' + cls.CONTENT_WRAP_CLASS) as HTMLElement;
1088
+ const contentWrapRight: number = dragArea.getBoundingClientRect().right;
1089
+ const cursorDrag: boolean = this.parent.activeView.isTimelineView() && !this.parent.enableRtl &&
1090
+ this.actionObj.pageX > this.actionObj.clone.getBoundingClientRect().right &&
1091
+ !this.isMorePopupOpened && !(this.actionObj.pageX > contentWrapRight);
1092
+ const leftVal: number = (this.parent.eventDragArea) ? dragArea.scrollLeft - dragArea.offsetLeft : 0;
1093
+ if ((this.isCursorAhead || cursorDrag) && !this.isStepDragging) {
1094
+ this.isCursorAhead = true;
1095
+ }
1096
+ let cloneIndex: number =
1097
+ Math.floor((this.actionObj.pageX - this.actionObj.clone.getBoundingClientRect().left + leftVal) / this.actionObj.cellWidth);
1098
+ if (this.parent.enableRtl) {
1099
+ cloneIndex = Math.abs(Math.floor((this.actionObj.pageX - this.actionObj.clone.getBoundingClientRect().right) /
1100
+ this.actionObj.cellWidth)) - 1;
1101
+ }
1102
+ if (this.cursorPointIndex < 0) {
1103
+ this.cursorIndex(e, eventObj, offsetLeft, cloneIndex);
1104
+ }
1105
+ const tr: HTMLTableRowElement = this.parent.getContentTable().querySelector('tr') as HTMLTableRowElement;
1106
+ let index: number = this.getCursorCurrentIndex(colIndex, cloneIndex, tr);
1107
+ index = index < 0 ? 0 : index;
1108
+ let eventStart: Date = this.isHeaderRows ? new Date(this.timelineEventModule.dateRender[parseInt(index.toString(), 10)].getTime()) :
1109
+ this.parent.getDateFromElement(<HTMLElement>tr.children[parseInt(index.toString(), 10)]);
1110
+ eventStart = this.isAllDayDrag ? util.resetTime(eventStart) : eventStart;
1111
+ if (this.isStepDragging) {
1112
+ const widthDiff: number = this.getWidthDiff(tr, index);
1113
+ if (widthDiff !== 0) {
1114
+ let timeDiff: number = Math.ceil(widthDiff / this.widthPerMinute);
1115
+ eventStart.setMinutes(eventStart.getMinutes() + (timeDiff * this.actionObj.interval));
1116
+ if (this.isCursorAhead || cursorDrag) {
1117
+ eventStart.setMilliseconds(-(eventDuration));
1118
+ } else {
1119
+ eventStart.setMinutes(eventStart.getMinutes() - this.minDiff);
1120
+ const intervalInMS: number = this.actionObj.interval * util.MS_PER_MINUTE;
1121
+ timeDiff = Math.abs(eventStart.getTime() - this.actionObj.start.getTime()) / intervalInMS;
1122
+ const roundTimeDiff: number = Math.trunc(timeDiff);
1123
+ if (roundTimeDiff !== timeDiff) {
1124
+ timeDiff = (roundTimeDiff * intervalInMS) * (eventStart > this.actionObj.start ? 1 : -1);
1125
+ eventStart = new Date(this.actionObj.start.getTime() + timeDiff);
1126
+ }
1127
+ }
1128
+ } else {
1129
+ eventStart = this.actionObj.start;
1130
+ }
1131
+ } else {
1132
+ if ((this.isCursorAhead || cursorDrag) && !this.isAllDayDrag) {
1133
+ const minutes: number = this.isTimelineDayProcess || this.isAllDayDrag ? MINUTES_PER_DAY : this.actionObj.slotInterval;
1134
+ eventStart.setMinutes(eventStart.getMinutes() + minutes);
1135
+ eventStart.setMilliseconds(-(eventDuration));
1136
+ if (eventStart.getTime() === util.resetTime(eventStart).getTime() && eventStart.getMinutes() === 0 && eventDuration === 0) {
1137
+ eventStart.setMinutes(-minutes);
1138
+ }
1139
+ } else {
1140
+ eventStart.setMinutes(eventStart.getMinutes() - (this.cursorPointIndex *
1141
+ (this.isTimelineDayProcess || this.isAllDayDrag ? MINUTES_PER_DAY : this.actionObj.slotInterval)));
1142
+ }
1143
+ }
1144
+ if (!this.isStepDragging) {
1145
+ eventStart = this.calculateIntervalTime(eventStart);
1146
+ }
1147
+ if (this.isTimelineDayProcess || this.isAllDayDrag) {
1148
+ const eventSrt: Date = eventObj[this.parent.eventFields.startTime] as Date;
1149
+ eventStart.setHours(eventSrt.getHours(), eventSrt.getMinutes(), eventSrt.getSeconds());
1150
+ }
1151
+ if (this.parent.eventDragArea) {
1152
+ const targetDate: Date = this.parent.getDateFromElement(e.target as HTMLElement);
1153
+ if (!isNullOrUndefined(targetDate)) {
1154
+ if (!this.parent.activeViewOptions.timeScale.enable || (this.parent.currentView === 'TimelineMonth')) {
1155
+ const eventSrt: Date = eventObj[this.parent.eventFields.startTime];
1156
+ eventStart = new Date(targetDate.setHours(eventSrt.getHours(), eventSrt.getMinutes(), eventSrt.getSeconds()));
1157
+ } else {
1158
+ eventStart = targetDate;
1159
+ }
1160
+ }
1161
+ }
1162
+ const eventEnd: Date = new Date(eventStart.getTime());
1163
+ eventEnd.setMilliseconds(eventDuration);
1164
+ let eventsData: Record<string, any>[] = [this.getUpdatedEvent(eventStart, eventEnd, this.actionObj.event)];
1165
+ if (this.multiData.length > 0) {
1166
+ const startTimeDiff: number = (eventsData[0][this.parent.eventFields.startTime] as Date).getTime() - this.startTime;
1167
+ for (let i: number = 0; i < this.multiData.length; i++) {
1168
+ this.updatedData[parseInt(i.toString(), 10)] =
1169
+ this.updateMultipleData(this.multiData[parseInt(i.toString(), 10)], startTimeDiff);
1170
+ }
1171
+ eventsData = this.updatedData;
1172
+ }
1173
+ for (let dataIndex: number = 0; dataIndex < eventsData.length; dataIndex++) {
1174
+ const cloneElement: HTMLElement =
1175
+ this.multiData.length > 0 ? this.actionObj.cloneElement[parseInt(dataIndex.toString(), 10)] : this.actionObj.clone;
1176
+ if (isNullOrUndefined(this.parent.eventDragArea))
1177
+ {
1178
+ const events: Record<string, any>[] =
1179
+ this.timelineEventModule.splitEvent(eventsData[parseInt(dataIndex.toString(), 10)], this.timelineEventModule.dateRender);
1180
+ const eventData: Record<string, any> = events[0].data as Record<string, any>;
1181
+ const startTime: Date = this.timelineEventModule.getStartTime(events[0], eventData);
1182
+ const endTime: Date = this.timelineEventModule.getEndTime(events[0], eventData);
1183
+ // eslint-disable-next-line max-len
1184
+ const width: number = this.timelineEventModule.getEventWidth(startTime, endTime, eventObj[this.parent.eventFields.isAllDay] as boolean, eventData.count as number);
1185
+ // eslint-disable-next-line max-len
1186
+ let day: number = this.parent.getIndexOfDate(this.timelineEventModule.dateRender, util.resetTime(new Date(startTime.getTime())));
1187
+ day = day < 0 ? 0 : day;
1188
+ const left: number =
1189
+ this.timelineEventModule.getPosition(startTime, endTime, eventObj[this.parent.eventFields.isAllDay] as boolean, day);
1190
+ if (this.parent.enableRtl) {
1191
+ cloneElement.style.right = formatUnit(left);
1192
+ } else {
1193
+ cloneElement.style.left = formatUnit(left);
1194
+ }
1195
+ if (!this.isMorePopupOpened) {
1196
+ cloneElement.style.width = formatUnit(width);
1197
+ }
1198
+ }
1199
+ if (this.parent.activeViewOptions.group.resources.length > 0) {
1200
+ this.calculateResourceGroupingPosition(e, cloneElement);
1201
+ }
1202
+ this.actionObj.start = new Date(eventStart.getTime());
1203
+ this.actionObj.end = new Date(eventEnd.getTime());
1204
+ this.updateTimePosition(this.actionObj.start, this.updatedData);
1205
+ }
1206
+ }
1207
+
1208
+ private getOffsetValue(offsetLeft: number, rightOffset: number): number {
1209
+ if (this.scrollEdges.left || this.scrollEdges.right) {
1210
+ const viewEle: HTMLElement = this.parent.element.querySelector('.' + cls.CONTENT_WRAP_CLASS) as HTMLElement;
1211
+ if (this.parent.enableRtl) {
1212
+ rightOffset = viewEle.offsetWidth - viewEle.scrollLeft;
1213
+ if (this.scrollEdges.right) {
1214
+ rightOffset = (rightOffset - viewEle.offsetWidth + this.actionObj.clone.offsetWidth) -
1215
+ (this.actionObj.clone.offsetWidth - this.widthUptoCursorPoint);
1216
+ } else {
1217
+ rightOffset = rightOffset + this.widthUptoCursorPoint;
1218
+ if (rightOffset - this.widthUptoCursorPoint >= viewEle.scrollWidth) {
1219
+ this.actionObj.clone.style.width =
1220
+ formatUnit(this.actionObj.clone.offsetWidth - this.widthUptoCursorPoint + this.actionObj.cellWidth);
1221
+ rightOffset = (viewEle.scrollLeft - viewEle.scrollWidth);
1222
+ }
1223
+ }
1224
+ if (isNullOrUndefined(this.parent.eventDragArea)) {
1225
+ this.actionObj.clone.style.left = formatUnit(rightOffset);
1226
+ }
1227
+ } else {
1228
+ if (this.scrollEdges.left) {
1229
+ offsetLeft = viewEle.scrollLeft - this.widthUptoCursorPoint + this.actionObj.cellWidth;
1230
+ if (viewEle.scrollLeft + viewEle.offsetWidth >= viewEle.offsetWidth) {
1231
+ viewEle.scrollLeft = viewEle.scrollLeft - 1;
1232
+ } else if (this.actionObj.clone.offsetLeft === 0) {
1233
+ offsetLeft = viewEle.scrollLeft;
1234
+ }
1235
+ } else {
1236
+ offsetLeft = (viewEle.scrollLeft + viewEle.offsetWidth -
1237
+ this.actionObj.clone.offsetWidth) + (this.actionObj.clone.offsetWidth - this.widthUptoCursorPoint);
1238
+ }
1239
+ offsetLeft = offsetLeft < 0 ? 0 : offsetLeft;
1240
+ if (isNullOrUndefined(this.parent.eventDragArea)) {
1241
+ this.actionObj.clone.style.left = formatUnit(offsetLeft);
1242
+ }
1243
+ }
1244
+ }
1245
+ return offsetLeft;
1246
+ }
1247
+
1248
+ private getWidthDiff(tr: HTMLTableRowElement, index: number): number {
1249
+ const pages: ClientRect | DOMRect = this.scrollArgs.element.getBoundingClientRect();
1250
+ if (pages.left <= this.actionObj.pageX && pages.right >= this.actionObj.pageX) {
1251
+ const targetLeft: number = (<HTMLElement>tr.children[parseInt(index.toString(), 10)]).offsetLeft;
1252
+ const pageX: number = this.actionObj.pageX - pages.left;
1253
+ if (this.parent.enableRtl) {
1254
+ return (targetLeft + this.actionObj.cellWidth) - (this.scrollArgs.element.scrollLeft + pageX);
1255
+ } else {
1256
+ return (this.scrollArgs.element.scrollLeft + pageX) - targetLeft;
1257
+ }
1258
+ }
1259
+ return 0;
1260
+ }
1261
+
1262
+ private getColumnIndex(offsetLeft: number): number {
1263
+ const index: number = Math.round(offsetLeft / this.actionObj.cellWidth);
1264
+ if (this.isHeaderRows) {
1265
+ return index;
1266
+ }
1267
+ return this.getIndex(index);
1268
+ }
1269
+
1270
+ private getCursorCurrentIndex(colIndex: number, cloneIndex: number, tr: HTMLTableRowElement): number {
1271
+ const index: number = colIndex + cloneIndex;
1272
+ if (this.isHeaderRows) {
1273
+ const dateLength: number = Math.floor(tr.offsetWidth / this.actionObj.cellWidth);
1274
+ return (index > dateLength - 1) ? dateLength - 1 : index;
1275
+ }
1276
+ return (index > tr.children.length - 1) ? tr.children.length - 1 : index;
1277
+ }
1278
+
1279
+ private cursorIndex(e: MouseEvent & TouchEvent, event: Record<string, any>, left: number, index: number): void {
1280
+ const td: HTMLElement = (<HTMLElement>closest(e.target as Element, '.e-work-cells'));
1281
+ if (!isNullOrUndefined(td) && !this.isMorePopupOpened) {
1282
+ let targetDate: Date = this.parent.getDateFromElement(td);
1283
+ targetDate = this.isAllDayDrag ? util.resetTime(targetDate) : targetDate;
1284
+ if (this.isHeaderRows) {
1285
+ const currentIndex: number = Math.floor(left / this.actionObj.cellWidth);
1286
+ targetDate = new Date(this.timelineEventModule.dateRender[currentIndex + index].getTime());
1287
+ }
1288
+ const timeDiff: number = targetDate.getTime() - (event[this.parent.eventFields.startTime] as Date).getTime();
1289
+ if (this.isTimelineDayProcess || this.isAllDayDrag) {
1290
+ this.cursorPointIndex = Math.abs(Math.ceil(timeDiff / (util.MS_PER_DAY)));
1291
+ } else {
1292
+ const widthDiff: number =
1293
+ Math.floor((timeDiff / util.MS_PER_MINUTE) / (this.actionObj.slotInterval / this.actionObj.cellWidth));
1294
+ this.cursorPointIndex = Math.floor(widthDiff / this.actionObj.cellWidth);
1295
+ this.cursorPointIndex = this.cursorPointIndex < 0 ? 0 : this.cursorPointIndex;
1296
+ }
1297
+ } else {
1298
+ this.cursorPointIndex = 0;
1299
+ }
1300
+ }
1301
+
1302
+ private calculateResourceGroupingPosition(e: MouseEvent & TouchEvent, cloneElement: HTMLElement): void {
1303
+ const dragArea: HTMLElement = this.parent.element.querySelector('.' + cls.CONTENT_WRAP_CLASS) as HTMLElement;
1304
+ const trCollection: HTMLElement[] =
1305
+ [].slice.call(this.parent.element.querySelectorAll('.e-content-wrap .e-content-table tr:not(.e-hidden)'));
1306
+ let translateY: number = util.getTranslateY(dragArea.querySelector('table'));
1307
+ translateY = (isNullOrUndefined(translateY)) ? 0 : translateY;
1308
+ const rowHeight: number = (this.parent.rowAutoHeight) ?
1309
+ ~~(dragArea.querySelector('table').offsetHeight / trCollection.length) : this.actionObj.cellHeight;
1310
+ let rowIndex: number = Math.floor(Math.floor((this.actionObj.Y +
1311
+ (dragArea.scrollTop - translateY - (window.scrollY || window.pageYOffset))) -
1312
+ util.getElementTop(dragArea, this.parent.uiStateValues.isTransformed)) / rowHeight);
1313
+ rowIndex = (rowIndex < 0) ? 0 : (rowIndex > trCollection.length - 1) ? trCollection.length - 1 : rowIndex;
1314
+ this.actionObj.index = rowIndex;
1315
+ const eventContainer: Element = this.parent.element.querySelectorAll('.e-appointment-container:not(.e-hidden)').item(rowIndex);
1316
+ let eventWrapper: HTMLElement = eventContainer.querySelector('.' + cls.APPOINTMENT_WRAPPER_CLASS) as HTMLElement;
1317
+ if (!eventWrapper) {
1318
+ eventWrapper = createElement('div', { className: cls.APPOINTMENT_WRAPPER_CLASS });
1319
+ eventContainer.appendChild(eventWrapper);
1320
+ }
1321
+ this.appendCloneElement(eventWrapper, cloneElement);
1322
+ const td: HTMLTableCellElement = closest((<HTMLTableCellElement>this.actionObj.target), 'td') as HTMLTableCellElement;
1323
+ this.actionObj.groupIndex = (td && !isNaN(parseInt(td.getAttribute('data-group-index'), 10)))
1324
+ ? parseInt(td.getAttribute('data-group-index'), 10) : this.actionObj.groupIndex;
1325
+ if (!isNullOrUndefined(this.parent.eventDragArea)) {
1326
+ return;
1327
+ }
1328
+ let top: number = this.parent.getElementHeight((<HTMLElement>trCollection[parseInt(rowIndex.toString(), 10)])) * rowIndex;
1329
+ if (this.parent.rowAutoHeight) {
1330
+ const cursorElement: HTMLElement = this.getCursorElement(e);
1331
+ if (cursorElement) {
1332
+ top = cursorElement.classList.contains(cls.WORK_CELLS_CLASS) ? cursorElement.offsetTop :
1333
+ (cursorElement.offsetParent && cursorElement.offsetParent.classList.contains(cls.APPOINTMENT_CLASS)) ?
1334
+ (cursorElement.offsetParent as HTMLElement).offsetTop : top;
1335
+ }
1336
+ }
1337
+ cloneElement.style.top = formatUnit(top);
1338
+ }
1339
+
1340
+ private appendCloneElement(element: HTMLElement, cloneElement: HTMLElement = null): void {
1341
+ cloneElement = isNullOrUndefined(cloneElement) ? this.actionObj.clone : cloneElement;
1342
+ const dragElement: HTMLElement = document.querySelector(this.parent.eventDragArea);
1343
+ if (this.parent.eventDragArea && dragElement) {
1344
+ dragElement.appendChild(cloneElement);
1345
+ } else {
1346
+ element.appendChild(cloneElement);
1347
+ }
1348
+ }
1349
+
1350
+ private getEventWrapper(index: number, isAllDayDrag?: boolean): HTMLElement {
1351
+ let eventWrapper: HTMLElement;
1352
+ if (isNullOrUndefined(isAllDayDrag)) {
1353
+ isAllDayDrag = this.actionObj.clone.classList.contains(cls.ALLDAY_APPOINTMENT_CLASS);
1354
+ }
1355
+ if (this.parent.activeViewOptions.timeScale.enable) {
1356
+ const wrapperClass: string = isAllDayDrag ? '.' + cls.ALLDAY_APPOINTMENT_WRAPPER_CLASS : '.' + cls.APPOINTMENT_WRAPPER_CLASS;
1357
+ eventWrapper = this.parent.element.querySelectorAll(wrapperClass).item(index) as HTMLElement;
1358
+ } else {
1359
+ const targetWrapper: HTMLElement = this.parent.element.querySelectorAll('.' + cls.WORK_CELLS_CLASS).item(index) as HTMLElement;
1360
+ eventWrapper = targetWrapper.querySelector('.' + cls.APPOINTMENT_WRAPPER_CLASS) as HTMLElement;
1361
+ if (!eventWrapper) {
1362
+ eventWrapper = createElement('div', { className: cls.APPOINTMENT_WRAPPER_CLASS });
1363
+ targetWrapper.appendChild(eventWrapper);
1364
+ }
1365
+ }
1366
+ return eventWrapper;
1367
+ }
1368
+
1369
+ private getAllDayEventHeight(): number {
1370
+ const eventWrapper: HTMLElement = createElement('div', { className: cls.APPOINTMENT_CLASS });
1371
+ this.parent.element.querySelector('.' + cls.ALLDAY_APPOINTMENT_WRAPPER_CLASS).appendChild(eventWrapper);
1372
+ const eventHeight: number = eventWrapper.offsetHeight;
1373
+ remove(eventWrapper);
1374
+ return eventHeight;
1375
+ }
1376
+
1377
+ private isAllowDrop(e: MouseEvent): boolean {
1378
+ if (!this.actionObj.excludeSelectors) {
1379
+ return false;
1380
+ }
1381
+ const dropSelectors: string[] = this.actionObj.excludeSelectors.split(',');
1382
+ let isAllowDrop: boolean = false;
1383
+ for (const selector of dropSelectors) {
1384
+ if ((<HTMLElement>e.target).classList.contains(selector)) {
1385
+ isAllowDrop = true;
1386
+ break;
1387
+ }
1388
+ }
1389
+ return isAllowDrop;
1390
+ }
1391
+
1392
+ /**
1393
+ * Get module name.
1394
+ *
1395
+ * @returns {string} Returns the module name
1396
+ */
1397
+ protected getModuleName(): string {
1398
+ return 'dragAndDrop';
1399
+ }
1400
+
1401
+ }