@syncfusion/ej2-schedule 30.2.7 → 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 (304) 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 +110 -36
  5. package/dist/es6/ej2-schedule.es2015.js.map +1 -1
  6. package/dist/es6/ej2-schedule.es5.js +110 -36
  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 +8 -5
  167. package/src/schedule/base/css-constant.d.ts +2 -0
  168. package/src/schedule/base/css-constant.js +2 -0
  169. package/src/schedule/base/schedule.js +15 -1
  170. package/src/schedule/event-renderer/agenda-base.d.ts +1 -1
  171. package/src/schedule/event-renderer/agenda-base.js +5 -4
  172. package/src/schedule/event-renderer/inline-edit.js +11 -6
  173. package/src/schedule/event-renderer/month.js +5 -3
  174. package/src/schedule/event-renderer/vertical-view.js +3 -0
  175. package/src/schedule/event-renderer/year.d.ts +2 -0
  176. package/src/schedule/event-renderer/year.js +28 -4
  177. package/src/schedule/popups/event-tooltip.js +4 -0
  178. package/src/schedule/popups/event-window.js +2 -2
  179. package/src/schedule/popups/quick-popups.js +5 -1
  180. package/src/schedule/renderer/agenda.js +3 -2
  181. package/src/schedule/renderer/vertical-view.js +1 -1
  182. package/src/schedule/renderer/year.js +3 -2
  183. package/styles/bds-lite.css +11 -8
  184. package/styles/bds.css +11 -8
  185. package/styles/bootstrap-dark-lite.css +12 -9
  186. package/styles/bootstrap-dark.css +12 -9
  187. package/styles/bootstrap-lite.css +12 -9
  188. package/styles/bootstrap.css +12 -9
  189. package/styles/bootstrap4-lite.css +11 -8
  190. package/styles/bootstrap4.css +11 -8
  191. package/styles/bootstrap5-dark-lite.css +11 -8
  192. package/styles/bootstrap5-dark.css +11 -8
  193. package/styles/bootstrap5-lite.css +11 -8
  194. package/styles/bootstrap5.3-lite.css +11 -8
  195. package/styles/bootstrap5.3.css +11 -8
  196. package/styles/bootstrap5.css +11 -8
  197. package/styles/fabric-dark-lite.css +12 -9
  198. package/styles/fabric-dark.css +12 -9
  199. package/styles/fabric-lite.css +12 -9
  200. package/styles/fabric.css +12 -9
  201. package/styles/fluent-dark-lite.css +13 -10
  202. package/styles/fluent-dark.css +13 -10
  203. package/styles/fluent-lite.css +13 -10
  204. package/styles/fluent.css +13 -10
  205. package/styles/fluent2-lite.css +11 -8
  206. package/styles/fluent2.css +11 -8
  207. package/styles/highcontrast-light-lite.css +12 -9
  208. package/styles/highcontrast-light.css +12 -9
  209. package/styles/highcontrast-lite.css +12 -9
  210. package/styles/highcontrast.css +12 -9
  211. package/styles/material-dark-lite.css +12 -9
  212. package/styles/material-dark.css +12 -9
  213. package/styles/material-lite.css +12 -9
  214. package/styles/material.css +12 -9
  215. package/styles/material3-dark-lite.css +11 -8
  216. package/styles/material3-dark.css +11 -8
  217. package/styles/material3-lite.css +11 -8
  218. package/styles/material3.css +11 -8
  219. package/styles/recurrence-editor/_bds-definition.scss +1 -0
  220. package/styles/recurrence-editor/_bootstrap-dark-definition.scss +1 -0
  221. package/styles/recurrence-editor/_bootstrap-definition.scss +1 -0
  222. package/styles/recurrence-editor/_bootstrap4-definition.scss +1 -0
  223. package/styles/recurrence-editor/_bootstrap5-definition.scss +1 -0
  224. package/styles/recurrence-editor/_bootstrap5.3-definition.scss +1 -0
  225. package/styles/recurrence-editor/_fabric-dark-definition.scss +1 -0
  226. package/styles/recurrence-editor/_fabric-definition.scss +1 -0
  227. package/styles/recurrence-editor/_fluent-definition.scss +1 -0
  228. package/styles/recurrence-editor/_fluent2-definition.scss +1 -0
  229. package/styles/recurrence-editor/_fusionnew-definition.scss +1 -0
  230. package/styles/recurrence-editor/_highcontrast-definition.scss +1 -0
  231. package/styles/recurrence-editor/_highcontrast-light-definition.scss +1 -0
  232. package/styles/recurrence-editor/_layout.scss +5 -1
  233. package/styles/recurrence-editor/_material-dark-definition.scss +1 -0
  234. package/styles/recurrence-editor/_material-definition.scss +1 -0
  235. package/styles/recurrence-editor/_material3-definition.scss +1 -0
  236. package/styles/recurrence-editor/_tailwind-definition.scss +1 -0
  237. package/styles/recurrence-editor/_tailwind3-definition.scss +1 -0
  238. package/styles/recurrence-editor/bds.css +3 -0
  239. package/styles/recurrence-editor/bootstrap-dark.css +4 -1
  240. package/styles/recurrence-editor/bootstrap.css +4 -1
  241. package/styles/recurrence-editor/bootstrap4.css +3 -0
  242. package/styles/recurrence-editor/bootstrap5-dark.css +3 -0
  243. package/styles/recurrence-editor/bootstrap5.3.css +3 -0
  244. package/styles/recurrence-editor/bootstrap5.css +3 -0
  245. package/styles/recurrence-editor/fabric-dark.css +4 -1
  246. package/styles/recurrence-editor/fabric.css +4 -1
  247. package/styles/recurrence-editor/fluent-dark.css +4 -1
  248. package/styles/recurrence-editor/fluent.css +4 -1
  249. package/styles/recurrence-editor/fluent2.css +3 -0
  250. package/styles/recurrence-editor/highcontrast-light.css +4 -1
  251. package/styles/recurrence-editor/highcontrast.css +4 -1
  252. package/styles/recurrence-editor/material-dark.css +4 -1
  253. package/styles/recurrence-editor/material.css +4 -1
  254. package/styles/recurrence-editor/material3-dark.css +3 -0
  255. package/styles/recurrence-editor/material3.css +3 -0
  256. package/styles/recurrence-editor/tailwind-dark.css +3 -0
  257. package/styles/recurrence-editor/tailwind.css +3 -0
  258. package/styles/recurrence-editor/tailwind3.css +3 -0
  259. package/styles/schedule/_bds-definition.scss +2 -0
  260. package/styles/schedule/_bootstrap-dark-definition.scss +2 -0
  261. package/styles/schedule/_bootstrap-definition.scss +2 -0
  262. package/styles/schedule/_bootstrap4-definition.scss +2 -0
  263. package/styles/schedule/_bootstrap5-definition.scss +2 -0
  264. package/styles/schedule/_bootstrap5.3-definition.scss +2 -0
  265. package/styles/schedule/_fabric-dark-definition.scss +2 -0
  266. package/styles/schedule/_fabric-definition.scss +2 -0
  267. package/styles/schedule/_fluent-definition.scss +3 -1
  268. package/styles/schedule/_fluent2-definition.scss +2 -0
  269. package/styles/schedule/_fusionnew-definition.scss +2 -0
  270. package/styles/schedule/_highcontrast-definition.scss +2 -0
  271. package/styles/schedule/_highcontrast-light-definition.scss +2 -0
  272. package/styles/schedule/_layout.scss +12 -11
  273. package/styles/schedule/_material-dark-definition.scss +2 -0
  274. package/styles/schedule/_material-definition.scss +2 -0
  275. package/styles/schedule/_material3-definition.scss +2 -0
  276. package/styles/schedule/_tailwind-definition.scss +2 -0
  277. package/styles/schedule/_tailwind3-definition.scss +2 -0
  278. package/styles/schedule/bds.css +8 -8
  279. package/styles/schedule/bootstrap-dark.css +8 -8
  280. package/styles/schedule/bootstrap.css +8 -8
  281. package/styles/schedule/bootstrap4.css +8 -8
  282. package/styles/schedule/bootstrap5-dark.css +8 -8
  283. package/styles/schedule/bootstrap5.3.css +8 -8
  284. package/styles/schedule/bootstrap5.css +8 -8
  285. package/styles/schedule/fabric-dark.css +8 -8
  286. package/styles/schedule/fabric.css +8 -8
  287. package/styles/schedule/fluent-dark.css +9 -9
  288. package/styles/schedule/fluent.css +9 -9
  289. package/styles/schedule/fluent2.css +8 -8
  290. package/styles/schedule/highcontrast-light.css +8 -8
  291. package/styles/schedule/highcontrast.css +8 -8
  292. package/styles/schedule/material-dark.css +8 -8
  293. package/styles/schedule/material.css +8 -8
  294. package/styles/schedule/material3-dark.css +8 -8
  295. package/styles/schedule/material3.css +8 -8
  296. package/styles/schedule/tailwind-dark.css +8 -8
  297. package/styles/schedule/tailwind.css +8 -8
  298. package/styles/schedule/tailwind3.css +8 -8
  299. package/styles/tailwind-dark-lite.css +11 -8
  300. package/styles/tailwind-dark.css +11 -8
  301. package/styles/tailwind-lite.css +11 -8
  302. package/styles/tailwind.css +11 -8
  303. package/styles/tailwind3-lite.css +11 -8
  304. package/styles/tailwind3.css +11 -8
@@ -0,0 +1,898 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import { append, createElement, extend, EventHandler, Animation, formatUnit, closest } from '@syncfusion/ej2-base';
3
+ import { isNullOrUndefined, setStyleAttribute, remove, removeClass, addClass } from '@syncfusion/ej2-base';
4
+ import { EventFieldsMapping, ElementData, EventRenderedArgs, TdData } from '../base/interface';
5
+ import { Schedule } from '../base/schedule';
6
+ import { EventBase } from './event-base';
7
+ import * as util from '../base/util';
8
+ import * as events from '../base/constant';
9
+ import * as cls from '../base/css-constant';
10
+
11
+ /**
12
+ * Vertical view appointment rendering
13
+ */
14
+ export class VerticalEvent extends EventBase {
15
+ public dateRender: Date[][] = [];
16
+ private renderedEvents: Record<string, any>[][] = [];
17
+ private renderedAllDayEvents: Record<string, any>[][] = [];
18
+ private overlapEvents: Record<string, any>[][] = [];
19
+ private moreEvents: HTMLElement[] = [];
20
+ private overlapList: Record<string, any>[] = [];
21
+ private allDayEvents: Record<string, any>[] = [];
22
+ private slotCount: number = this.parent.activeViewOptions.timeScale.slotCount;
23
+ private interval: number = this.parent.activeViewOptions.timeScale.interval;
24
+ public allDayLevel: number = 0;
25
+ private startHour: Date = this.getStartEndHours(this.parent.activeViewOptions.startHour);
26
+ private endHour: Date = this.getStartEndHours(this.parent.activeViewOptions.endHour);
27
+ private element: HTMLElement;
28
+ public allDayElement: HTMLElement[];
29
+ private animation: Animation;
30
+ public fields: EventFieldsMapping;
31
+ public cellHeight: number;
32
+ public resources: TdData[];
33
+ private isResourceEventTemplate: boolean;
34
+
35
+ constructor(parent: Schedule) {
36
+ super(parent);
37
+ this.element = this.parent.activeView.getPanel();
38
+ this.fields = this.parent.eventFields;
39
+ this.animation = new Animation({ progress: this.animationUiUpdate.bind(this) });
40
+ this.addEventListener();
41
+ }
42
+
43
+ public renderAppointments(): void {
44
+ if (isNullOrUndefined(this.parent)) { return; }
45
+
46
+ if (this.parent.dragAndDropModule) {
47
+ this.parent.dragAndDropModule.setDragArea();
48
+ }
49
+
50
+ this.isResourceEventTemplate = this.parent.isSpecificResourceEvents();
51
+ const wrapperElements: HTMLElement[] = [].slice.call(this.parent.element.querySelectorAll('.' + cls.BLOCK_APPOINTMENT_CLASS +
52
+ ',.' + cls.APPOINTMENT_CLASS + ',.' + cls.ROW_COUNT_WRAPPER_CLASS));
53
+ const isDragging: boolean = (this.parent.crudModule && this.parent.crudModule.crudObj.isCrudAction) ? true : false;
54
+ const hideWrapper: (wrapper: HTMLElement) => void = (wrapper: HTMLElement): void => {
55
+ if ((this.parent as any).isReact && !isNullOrUndefined(this.parent.activeViewOptions.eventTemplate)) {
56
+ const appWrapper: Element = closest(wrapper, '.' + cls.DAY_WRAPPER_CLASS + ',.' + cls.ALLDAY_APPOINTMENT_WRAPPER_CLASS);
57
+ if (appWrapper && !appWrapper.classList.contains(cls.APPOINTMENT_WRAPPER_HIDDEN_CLASS)) {
58
+ addClass([appWrapper], cls.APPOINTMENT_WRAPPER_HIDDEN_CLASS);
59
+ }
60
+ }
61
+ };
62
+ for (const wrapper of wrapperElements) {
63
+ if (isDragging && !(wrapper.classList.contains(cls.ALLDAY_APPOINTMENT_CLASS) ||
64
+ wrapper.classList.contains(cls.ROW_COUNT_WRAPPER_CLASS))) {
65
+ const groupIndex: number = parseInt(wrapper.getAttribute('data-group-index'), 10);
66
+ for (let j: number = 0, len: number = this.parent.crudModule.crudObj.sourceEvent.length; j < len; j++) {
67
+ if (groupIndex === this.parent.crudModule.crudObj.sourceEvent[parseInt(j.toString(), 10)].groupIndex ||
68
+ groupIndex === this.parent.crudModule.crudObj.targetEvent[parseInt(j.toString(), 10)].groupIndex) {
69
+ hideWrapper(wrapper);
70
+ remove(wrapper);
71
+ }
72
+ }
73
+ } else {
74
+ hideWrapper(wrapper);
75
+ remove(wrapper);
76
+ }
77
+ }
78
+ if (!this.element.querySelector('.' + cls.WORK_CELLS_CLASS)) {
79
+ return;
80
+ }
81
+ if (this.parent.virtualScrollModule) {
82
+ this.parent.virtualScrollModule.updateFocusedWorkCell();
83
+ }
84
+ this.allDayElement = [].slice.call(this.element.querySelectorAll('.' + cls.ALLDAY_CELLS_CLASS));
85
+ this.setAllDayRowHeight(0);
86
+ if (this.parent.eventsProcessed.length === 0 && this.parent.blockProcessed.length === 0) {
87
+ return;
88
+ }
89
+ const expandCollapse: HTMLElement = this.element.querySelector('.' + cls.ALLDAY_APPOINTMENT_SECTION_CLASS) as HTMLElement;
90
+ EventHandler.remove(expandCollapse, 'click', this.rowExpandCollapse);
91
+ EventHandler.add(expandCollapse, 'click', this.rowExpandCollapse, this);
92
+ this.renderedEvents = [];
93
+ this.renderedAllDayEvents = [];
94
+ this.initializeValues();
95
+ this.processBlockEvents();
96
+ this.renderEvents('normalEvents');
97
+ if (this.allDayEvents.length > 0) {
98
+ this.allDayEvents = this.allDayEvents.filter((item: Record<string, any>, index: number, arr: Record<string, any>[]) =>
99
+ index === arr.map((item: Record<string, any>) => item.Guid).indexOf(item.Guid));
100
+ removeClass(this.allDayElement, cls.ALLDAY_ROW_ANIMATE_CLASS);
101
+ this.slots.push(this.parent.activeView.renderDates.map((date: Date) => +date) as any);
102
+ this.renderEvents('allDayEvents');
103
+ this.animation.animate(this.allDayElement[0] as HTMLElement);
104
+ }
105
+ this.parent.notify(events.contentReady, {});
106
+ addClass(this.allDayElement, cls.ALLDAY_ROW_ANIMATE_CLASS);
107
+ if (isDragging) {
108
+ this.parent.crudModule.crudObj.isCrudAction = false;
109
+ }
110
+ this.parent.renderTemplates(() => {
111
+ if (this.parent && (this.parent as any).isReact && this.parent.activeViewOptions.eventTemplate) {
112
+ const wraps: Element[] = [].slice.call(this.parent.element.querySelectorAll('.' + cls.APPOINTMENT_WRAPPER_HIDDEN_CLASS));
113
+ removeClass(wraps, cls.APPOINTMENT_WRAPPER_HIDDEN_CLASS);
114
+ }
115
+ });
116
+ }
117
+
118
+ public initializeValues(): void {
119
+ this.resources = (this.parent.activeViewOptions.group.resources.length > 0) ? this.parent.uiStateValues.isGroupAdaptive ?
120
+ [this.parent.resourceBase.lastResourceLevel[this.parent.uiStateValues.groupIndex]] :
121
+ this.parent.resourceBase.lastResourceLevel : [];
122
+ if (this.resources.length > 0 && this.parent.activeViewOptions.allowVirtualScrolling && this.parent.virtualScrollModule) {
123
+ this.resources = this.parent.resourceBase.renderedResources;
124
+ }
125
+ this.cellHeight =
126
+ parseFloat(this.parent.getElementHeight(this.parent.element.querySelector('.e-content-wrap tbody tr')).toFixed(2));
127
+ this.dateRender[0] = this.parent.activeView.renderDates;
128
+ if (this.parent.activeViewOptions.group.resources.length > 0) {
129
+ for (let i: number = 0, len: number = this.resources.length; i < len; i++) {
130
+ this.dateRender[parseInt(i.toString(), 10)] = this.resources[parseInt(i.toString(), 10)].renderDates;
131
+ }
132
+ }
133
+ }
134
+
135
+ public getHeight(start: Date, end: Date): number {
136
+ let appHeight: number = (util.getUniversalTime(end) - util.getUniversalTime(start)) /
137
+ util.MS_PER_MINUTE * (this.cellHeight * this.slotCount) / this.interval;
138
+ appHeight = (appHeight <= 0) ? this.cellHeight : appHeight;
139
+ return appHeight;
140
+ }
141
+
142
+ private appendEvent(eventObj: Record<string, any>, appointmentElement: HTMLElement, index: number, appLeft: string): void {
143
+ const appointmentWrap: HTMLElement = this.element.querySelector('.' + cls.APPOINTMENT_WRAPPER_CLASS + '[id="' + cls.APPOINTMENT_WRAPPER_CLASS + '-' + index + '"]');
144
+ if (this.parent.enableRtl) {
145
+ setStyleAttribute(appointmentElement, { 'right': appLeft });
146
+ } else {
147
+ setStyleAttribute(appointmentElement, { 'left': appLeft });
148
+ }
149
+ const eventType: string = appointmentElement.classList.contains(cls.BLOCK_APPOINTMENT_CLASS) ? 'blockEvent' : 'event';
150
+ const args: EventRenderedArgs = {
151
+ data: extend({}, eventObj, null, true) as Record<string, any>,
152
+ element: appointmentElement, cancel: false, type: eventType
153
+ };
154
+ this.parent.trigger(events.eventRendered, args, (eventArgs: EventRenderedArgs) => {
155
+ if (!eventArgs.cancel) {
156
+ appointmentWrap.appendChild(appointmentElement);
157
+ }
158
+ });
159
+ }
160
+
161
+ private processBlockEvents(): void {
162
+ const resources: number[] = this.getResourceList();
163
+ let dateCount: number = this.getStartCount();
164
+ for (const resource of resources) {
165
+ const renderDates: Date[] = this.dateRender[parseInt(resource.toString(), 10)];
166
+ for (let day: number = 0, length: number = renderDates.length; day < length; day++) {
167
+ const startDate: Date = new Date(renderDates[parseInt(day.toString(), 10)].getTime());
168
+ const endDate: Date = util.resetTime(util.addDays(renderDates[parseInt(day.toString(), 10)], 1));
169
+ const filterEvents: Record<string, any>[] =
170
+ this.filterEvents(startDate, endDate, this.parent.blockProcessed, this.resources[parseInt(resource.toString(), 10)]);
171
+ for (const event of filterEvents) {
172
+ if (this.parent.resourceBase) {
173
+ this.setValues(event, resource);
174
+ }
175
+ this.renderBlockEvents(event, day, resource, dateCount);
176
+ this.cssClass = null;
177
+ this.groupOrder = null;
178
+ }
179
+ dateCount += 1;
180
+ }
181
+ }
182
+ }
183
+
184
+ private renderBlockEvents(eventObj: Record<string, any>, dayIndex: number, resource: number, dayCount: number): void {
185
+ const spannedData: Record<string, any> = this.isSpannedEvent(eventObj, dayIndex, resource);
186
+ const eStart: Date = spannedData[this.fields.startTime] as Date;
187
+ const eEnd: Date = spannedData[this.fields.endTime] as Date;
188
+ const currentDate: Date =
189
+ util.resetTime(new Date(this.dateRender[parseInt(resource.toString(), 10)][parseInt(dayIndex.toString(), 10)].getTime()));
190
+ const schedule: { [key: string]: Date } = util.getStartEndHours(currentDate, this.startHour, this.endHour);
191
+ if (eStart <= eEnd && this.isValidEvent(eventObj, eStart, eEnd, schedule) && this.isWorkDayAvailable(resource, eStart)) {
192
+ let blockTop: string;
193
+ let blockHeight: string;
194
+ if (spannedData[this.fields.isAllDay]) {
195
+ const contentWrap: HTMLElement = this.parent.element.querySelector('.' + cls.CONTENT_WRAP_CLASS + ' table') as HTMLElement;
196
+ blockHeight = formatUnit(contentWrap.offsetHeight);
197
+ blockTop = formatUnit(0);
198
+ } else {
199
+ blockHeight = formatUnit(this.getHeight(eStart, eEnd));
200
+ blockTop = formatUnit(this.getTopValue(eStart));
201
+ }
202
+ if (eventObj.IsBlock) {
203
+ blockHeight = formatUnit(parseInt(blockHeight, 10) - 1);
204
+ }
205
+ const appointmentElement: HTMLElement = this.createBlockAppointmentElement(eventObj, resource, this.isResourceEventTemplate);
206
+ const appWidth: string = eventObj.IsBlock ? '99%' : '100%';
207
+ setStyleAttribute(appointmentElement, { 'width': appWidth, 'height': blockHeight, 'top': blockTop });
208
+ const index: number = this.getDayIndex(dayIndex, resource, dayCount);
209
+ const appLeft: string = eventObj.IsBlock ? '0.5px' : '0px';
210
+ this.appendEvent(eventObj, appointmentElement, index, appLeft);
211
+ }
212
+ }
213
+
214
+ private renderEvents(eventType: string): void {
215
+ removeClass(this.allDayElement, cls.ALLDAY_ROW_ANIMATE_CLASS);
216
+ const eventCollection: Record<string, any>[] = (eventType === 'allDayEvents') ? this.sortByDateTime(this.allDayEvents) : undefined;
217
+ const resources: number[] = this.getResourceList();
218
+ let dateCount: number = this.getStartCount();
219
+ let isRender: boolean;
220
+ const appHeight: number = eventType === 'allDayEvents' ? this.parent.getElementHeightFromClass(
221
+ this.element.querySelector('.' + cls.ALLDAY_APPOINTMENT_WRAPPER_CLASS), cls.APPOINTMENT_CLASS) : 0;
222
+ const allDayRowTop: number = eventType === 'allDayEvents' && this.allDayElement.length > 0 ? this.allDayElement[0].offsetTop : 0;
223
+ for (const resource of resources) {
224
+ isRender = true;
225
+ if (this.parent.crudModule && this.parent.crudModule.crudObj.isCrudAction && eventType !== 'allDayEvents'
226
+ && !this.parent.uiStateValues.isGroupAdaptive) {
227
+ if (this.parent.crudModule.crudObj.sourceEvent.filter((data: TdData) => data.groupIndex === resource).length === 0 &&
228
+ this.parent.crudModule.crudObj.targetEvent.filter((data: TdData) => data.groupIndex === resource).length === 0) {
229
+ isRender = false;
230
+ }
231
+ }
232
+ this.slots = [];
233
+ const renderDates: Date[] = this.dateRender[parseInt(resource.toString(), 10)];
234
+ const renderedDate: Date[] = this.getRenderedDates(renderDates) || renderDates;
235
+ this.slots.push(renderDates.map((date: Date) => { return +date; }) as any);
236
+ for (let day: number = 0, length: number = renderDates.length; day < length &&
237
+ renderDates[parseInt(day.toString(), 10)] <= renderedDate[renderedDate.length - 1]; day++) {
238
+ this.renderedEvents = [];
239
+ const startDate: Date = new Date(renderDates[parseInt(day.toString(), 10)].getTime());
240
+ const endDate: Date = util.resetTime(util.addDays(renderDates[parseInt(day.toString(), 10)], 1));
241
+ const filterEvents: Record<string, any>[] =
242
+ this.filterEvents(startDate, endDate, eventCollection, this.resources[parseInt(resource.toString(), 10)]);
243
+ if (isRender) {
244
+ for (const event of filterEvents) {
245
+ if (this.parent.resourceBase) {
246
+ this.setValues(event, resource);
247
+ }
248
+ if (eventType === 'allDayEvents') {
249
+ this.renderAllDayEvents(event, day, resource, dateCount, false, allDayRowTop, appHeight);
250
+ } else {
251
+ if (this.isAllDayAppointment(event)) {
252
+ this.allDayEvents.push(extend({}, event, null, true) as Record<string, any>);
253
+ } else {
254
+ if (this.parent.eventSettings.enableMaxHeight) {
255
+ if (this.getOverlapIndex(event, day, false, resource) > 0) {
256
+ continue;
257
+ }
258
+ }
259
+ this.renderNormalEvents(event, day, resource, dateCount);
260
+ }
261
+ }
262
+ this.cssClass = null;
263
+ this.groupOrder = null;
264
+ }
265
+ } else {
266
+ for (const event of filterEvents) {
267
+ if (this.isAllDayAppointment(event)) {
268
+ this.allDayEvents.push(extend({}, event, null, true) as Record<string, any>);
269
+ }
270
+ }
271
+ }
272
+ dateCount += 1;
273
+ }
274
+ }
275
+ }
276
+
277
+ public getStartCount(): number {
278
+ return this.parent.virtualScrollModule && this.parent.activeViewOptions.allowVirtualScrolling && this.parent.timeScale.enable ?
279
+ parseInt(this.element.querySelector('.' + cls.APPOINTMENT_WRAPPER_CLASS).getAttribute('id').split('-').slice(-1)[0], 10) : 0;
280
+ }
281
+
282
+ private getDayIndex(dayIndex: number, resource: number, dayCount: number): number {
283
+ if (!this.parent.activeViewOptions.group.byDate) {
284
+ return dayCount;
285
+ }
286
+ if (this.parent.activeViewOptions.group.byDate && !this.parent.activeViewOptions.group.hideNonWorkingDays) {
287
+ const renderedIndex: number =
288
+ this.parent.resourceBase.lastResourceLevel[0].renderDates.indexOf(
289
+ this.dateRender[parseInt(resource.toString(), 10)][parseInt(dayIndex.toString(), 10)]);
290
+ return (this.resources.length * renderedIndex) + resource;
291
+ }
292
+ let dateIndex: number = 0;
293
+ const firstColumn: TdData[] = this.parent.activeView.colLevels[0];
294
+ const currentDate: number = this.dateRender[parseInt(resource.toString(), 10)][parseInt(dayIndex.toString(), 10)].getTime();
295
+ let currentResources: TdData[] = [];
296
+ for (let i: number = 0; i < firstColumn.length; i++) {
297
+ currentResources = this.parent.resourceBase.resourceDateTree[parseInt(i.toString(), 10)];
298
+ if (currentDate === firstColumn[parseInt(i.toString(), 10)].date.getTime()) {
299
+ break;
300
+ }
301
+ dateIndex = dateIndex + firstColumn[parseInt(i.toString(), 10)].colSpan;
302
+ }
303
+ const resIndex: number =
304
+ currentResources.findIndex((x: TdData) => x.groupOrder.toString() ===
305
+ this.resources[parseInt(resource.toString(), 10)].groupOrder.toString());
306
+ if (resIndex < 0) {
307
+ return dateIndex;
308
+ }
309
+ return dateIndex + resIndex;
310
+ }
311
+
312
+ private setValues(event: Record<string, any>, resourceIndex: number): void {
313
+ if (this.parent.activeViewOptions.group.resources.length > 0) {
314
+ this.cssClass = this.resources[parseInt(resourceIndex.toString(), 10)].cssClass;
315
+ this.groupOrder = this.resources[parseInt(resourceIndex.toString(), 10)].groupOrder;
316
+ } else {
317
+ this.cssClass = this.parent.resourceBase.getCssClass(event);
318
+ }
319
+ }
320
+
321
+ private getResourceList(): number[] {
322
+ // eslint-disable-next-line prefer-spread
323
+ const resources: number[] = Array.apply(null, {
324
+ length: (this.parent.activeViewOptions.group.resources.length > 0 && !this.parent.uiStateValues.isGroupAdaptive) ?
325
+ this.resources.length : 1
326
+ }).map((value: number, index: number) => { return index; });
327
+ return resources;
328
+ }
329
+
330
+ // eslint-disable-next-line max-len
331
+ public createAppointmentElement(record: Record<string, any>, isAllDay: boolean, data: Record<string, any>, resource: number): HTMLElement {
332
+ const fieldMapping: EventFieldsMapping = this.parent.eventFields;
333
+ const recordSubject: string = (record[fieldMapping.subject] || this.parent.eventSettings.fields.subject.default
334
+ || this.parent.localeObj.getConstant('addTitle')) as string;
335
+ const appointmentWrapper: HTMLElement = createElement('div', {
336
+ className: cls.APPOINTMENT_CLASS,
337
+ attrs: {
338
+ 'data-id': 'Appointment_' + record[fieldMapping.id],
339
+ 'data-guid': record.Guid as string,
340
+ 'role': 'button',
341
+ 'tabindex': '0',
342
+ 'aria-disabled': this.parent.eventBase.getReadonlyAttribute(record),
343
+ 'aria-label': this.parent.getAnnouncementString(record)
344
+ }
345
+ });
346
+ if (record[this.fields.isReadonly]) {
347
+ addClass([appointmentWrapper], 'e-read-only');
348
+ }
349
+ const appointmentDetails: HTMLElement = createElement('div', { className: cls.APPOINTMENT_DETAILS });
350
+ appointmentWrapper.appendChild(appointmentDetails);
351
+ if (this.parent.activeViewOptions.group.resources.length > 0) {
352
+ const resourceIndex: number = this.parent.uiStateValues.isGroupAdaptive ? this.parent.uiStateValues.groupIndex : resource;
353
+ appointmentWrapper.setAttribute('data-group-index', resourceIndex.toString());
354
+ }
355
+ let templateElement: HTMLElement[];
356
+ const eventData: Record<string, any> = data;
357
+ if (!isNullOrUndefined(this.parent.activeViewOptions.eventTemplate)) {
358
+ const elementId: string = this.parent.element.id + '_';
359
+ const viewName: string = this.parent.activeViewOptions.eventTemplateName;
360
+ const templateId: string = elementId + viewName + 'eventTemplate';
361
+ const resIndex: number = this.parent.uiStateValues.isGroupAdaptive ? this.parent.uiStateValues.groupIndex : resource;
362
+ const templateName: string = this.isResourceEventTemplate ? this.parent.getEventTemplateName(resIndex) : 'eventTemplate';
363
+ templateElement = this.parent.getAppointmentTemplate()(record, this.parent, templateName, templateId, false,
364
+ undefined, undefined, this.parent.root);
365
+ } else {
366
+ const appointmentSubject: HTMLElement = createElement('div', { className: cls.SUBJECT_CLASS });
367
+ this.parent.sanitize(recordSubject, appointmentSubject);
368
+ if (isAllDay) {
369
+ if (record[fieldMapping.isAllDay]) {
370
+ templateElement = [appointmentSubject];
371
+ } else {
372
+ templateElement = [];
373
+ const appointmentStartTime: HTMLElement = createElement('div', {
374
+ className: cls.APPOINTMENT_TIME + (this.parent.isAdaptive ? ' ' + cls.DISABLE_CLASS : ''),
375
+ innerHTML: this.parent.getTimeString(record[fieldMapping.startTime] as Date)
376
+ });
377
+ const appointmentEndTime: HTMLElement = createElement('div', {
378
+ className: cls.APPOINTMENT_TIME + (this.parent.isAdaptive ? ' ' + cls.DISABLE_CLASS : ''),
379
+ innerHTML: this.parent.getTimeString(record[fieldMapping.endTime] as Date)
380
+ });
381
+ addClass([appointmentSubject], 'e-text-center');
382
+ if (!eventData.isLeft) {
383
+ templateElement.push(appointmentStartTime);
384
+ }
385
+ templateElement.push(appointmentSubject);
386
+ if (!eventData.isRight) {
387
+ templateElement.push(appointmentEndTime);
388
+ }
389
+ }
390
+ } else {
391
+ const timeStr: string = this.parent.getTimeString(record[fieldMapping.startTime] as Date) + ' - ' +
392
+ this.parent.getTimeString(record[fieldMapping.endTime] as Date);
393
+ const appointmentTime: HTMLElement = createElement('div', {
394
+ className: cls.APPOINTMENT_TIME + (this.parent.isAdaptive ? ' ' + cls.DISABLE_CLASS : ''),
395
+ innerHTML: timeStr
396
+ });
397
+ const appointmentLocation: HTMLElement = createElement('div', { className: cls.LOCATION_CLASS });
398
+ this.parent.sanitize((record[fieldMapping.location] || this.parent.eventSettings.fields.location.default || '') as string,
399
+ appointmentLocation);
400
+ templateElement = [appointmentSubject, appointmentTime, appointmentLocation];
401
+ }
402
+ }
403
+ append(templateElement, appointmentDetails);
404
+ if (!this.parent.isAdaptive &&
405
+ (!isNullOrUndefined(record[fieldMapping.recurrenceRule]) || !isNullOrUndefined(record[fieldMapping.recurrenceID]))) {
406
+ const iconClass: string = (record[fieldMapping.id] === record[fieldMapping.recurrenceID]) ?
407
+ cls.EVENT_RECURRENCE_ICON_CLASS : cls.EVENT_RECURRENCE_EDIT_ICON_CLASS;
408
+ const recurrenceIcon: HTMLElement = createElement('div', { className: cls.ICON + ' ' + iconClass });
409
+ if (isAllDay) {
410
+ appointmentDetails.appendChild(recurrenceIcon);
411
+ } else {
412
+ appointmentWrapper.appendChild(recurrenceIcon);
413
+ }
414
+ }
415
+ this.parent.eventBase.renderSpannedIcon(isAllDay ? appointmentDetails : appointmentWrapper, eventData);
416
+ if (!isNullOrUndefined(this.cssClass)) {
417
+ addClass([appointmentWrapper], this.cssClass);
418
+ }
419
+ this.applyResourceColor(appointmentWrapper, record, 'backgroundColor', this.groupOrder);
420
+ this.renderResizeHandler(appointmentWrapper, eventData, record[this.fields.isReadonly] as boolean);
421
+ return appointmentWrapper;
422
+ }
423
+
424
+ private createMoreIndicator(allDayRow: HTMLElement[], count: number, currentDay: number): void {
425
+ const index: number = currentDay + count;
426
+ const countWrapper: HTMLElement = allDayRow[parseInt(index.toString(), 10)] as HTMLElement;
427
+ if (countWrapper.childElementCount <= 0) {
428
+ const innerCountWrap: Element = createElement('div', {
429
+ className: cls.ROW_COUNT_WRAPPER_CLASS,
430
+ id: cls.ROW_COUNT_WRAPPER_CLASS + '-' + index.toString()
431
+ });
432
+ const moreIndicatorElement: Element = createElement('div', {
433
+ className: cls.MORE_INDICATOR_CLASS,
434
+ attrs: { 'tabindex': '0', 'data-index': index.toString(), 'data-count': '1' },
435
+ innerHTML: '+1&nbsp;' + (this.parent.isAdaptive ? '' : this.parent.localeObj.getConstant('more'))
436
+ });
437
+ innerCountWrap.appendChild(moreIndicatorElement);
438
+ countWrapper.appendChild(innerCountWrap);
439
+ EventHandler.add(moreIndicatorElement, 'click', this.rowExpandCollapse, this);
440
+ } else {
441
+ const countCell: HTMLElement = countWrapper.querySelector('.' + cls.MORE_INDICATOR_CLASS) as HTMLElement;
442
+ const moreCount: number = parseInt(countCell.getAttribute('data-count'), 10) + 1;
443
+ countCell.setAttribute('data-count', moreCount.toString());
444
+ countCell.innerHTML = '+' + this.parent.globalize.formatNumber(moreCount) + '&nbsp;' + (this.parent.isAdaptive ? '' : this.parent.localeObj.getConstant('more'));
445
+ }
446
+ }
447
+
448
+ public isSpannedEvent(record: Record<string, any>, day: number, resource: number): Record<string, any> {
449
+ let currentDate: Date = util.resetTime(this.dateRender[parseInt(resource.toString(), 10)][parseInt(day.toString(), 10)]);
450
+ const renderedDate: Date[] = this.getRenderedDates(this.dateRender[parseInt(resource.toString(), 10)]) || [currentDate];
451
+ const currentDay: Date[] = renderedDate.filter((date: Date) => date.getDay() === day);
452
+ if (currentDay.length === 0) {
453
+ currentDate = util.resetTime(renderedDate[0]);
454
+ }
455
+ const field: EventFieldsMapping = this.parent.eventFields;
456
+ const schedule: Record<string, Date> = util.getStartEndHours(currentDate, this.startHour, this.endHour);
457
+ const event: Record<string, any> = extend({}, record, null, true) as Record<string, any>;
458
+ event.isSpanned = {
459
+ isBottom: false, isTop: false,
460
+ isSameDuration: event[field.startTime].getTime() === event[field.endTime].getTime()
461
+ };
462
+ if ((<Date>record[field.startTime]).getTime() < schedule.startHour.getTime()) {
463
+ event[field.startTime] = schedule.startHour;
464
+ (event.isSpanned as Record<string, any>).isTop = true;
465
+ }
466
+ if ((<Date>record[field.endTime]).getTime() > schedule.endHour.getTime()) {
467
+ event[field.endTime] = schedule.endHour;
468
+ (event.isSpanned as Record<string, any>).isBottom = true;
469
+ }
470
+ const eventDates: Record<string, Date> = this.updateEventMinimumDuration(schedule, event[field.startTime], event[field.endTime]);
471
+ event[field.startTime] = eventDates.startDate;
472
+ event[field.endTime] = eventDates.endDate;
473
+ return event;
474
+ }
475
+
476
+ private isWorkDayAvailable(resource: number, start: Date): boolean {
477
+ if (this.parent.activeViewOptions.group.hideNonWorkingDays && this.resources.length > 0) {
478
+ const workDays: number[] =
479
+ this.resources[parseInt(resource.toString(), 10)].
480
+ resourceData[this.resources[parseInt(resource.toString(), 10)].resource.workDaysField] ||
481
+ this.parent.activeViewOptions.workDays;
482
+ return workDays && workDays.indexOf(start.getDay()) >= 0;
483
+ }
484
+ return true;
485
+ }
486
+
487
+ // eslint-disable-next-line max-len
488
+ public renderAllDayEvents(eventObj: Record<string, any>, dayIndex: number, resource: number, dayCount: number, inline: boolean, cellTop: number, eventHeight: number): void {
489
+ let currentDates: Date[] = this.getRenderedDates(this.dateRender[parseInt(resource.toString(), 10)]) ||
490
+ this.dateRender[parseInt(resource.toString(), 10)];
491
+ if (this.parent.activeViewOptions.group.byDate) {
492
+ (this.slots as any)[0] = [this.dateRender[parseInt(resource.toString(), 10)][parseInt(dayIndex.toString(), 10)].getTime()];
493
+ currentDates = [this.dateRender[parseInt(resource.toString(), 10)][parseInt(dayIndex.toString(), 10)]];
494
+ }
495
+ const record: Record<string, any> = this.splitEvent(eventObj, currentDates)[0];
496
+ const eStart: Date = new Date((record[this.parent.eventFields.startTime] as Date).getTime());
497
+ const eEnd: Date = new Date((record[this.parent.eventFields.endTime] as Date).getTime());
498
+ if (eStart.getTime() < this.parent.minDate.getTime() || eEnd.getTime() > this.parent.maxDate.getTime()) {
499
+ return;
500
+ }
501
+ let appWidth: number = 0;
502
+ let topValue: number = 1;
503
+ const isDateRange: boolean = currentDates[0].getTime() <= eStart.getTime() &&
504
+ util.addDays(currentDates.slice(-1)[0], 1).getTime() >= eStart.getTime();
505
+ if (eStart <= eEnd && isDateRange && this.isWorkDayAvailable(resource, eStart)) {
506
+ let isAlreadyRendered: Record<string, any>[] = [];
507
+ if (this.renderedAllDayEvents[parseInt(resource.toString(), 10)]) {
508
+ isAlreadyRendered = this.renderedAllDayEvents[parseInt(resource.toString(), 10)].filter((event: Record<string, any>) =>
509
+ event.Guid === eventObj.Guid);
510
+ if (this.parent.activeViewOptions.group.byDate) {
511
+ isAlreadyRendered = isAlreadyRendered.filter((event: Record<string, any>) =>
512
+ event[this.parent.eventFields.startTime] >= currentDates[parseInt(dayIndex.toString(), 10)] &&
513
+ event[this.parent.eventFields.endTime] <=
514
+ util.addDays(new Date(+currentDates[parseInt(dayIndex.toString(), 10)]), 1)
515
+ );
516
+ }
517
+ }
518
+ if (isAlreadyRendered.length === 0) {
519
+ const allDayDifference: number = (record.data as Record<string, any>).count as number;
520
+ const allDayIndex: number = this.getOverlapIndex(record, dayIndex, true, resource);
521
+ record.Index = allDayIndex;
522
+ this.allDayLevel = (this.allDayLevel < allDayIndex) ? allDayIndex : this.allDayLevel;
523
+ const widthAdjustment: number = (<Record<string, any>>record.data).isRight ? 0 :
524
+ this.parent.currentView === 'Day' ? 4 : 7;
525
+ if (allDayDifference >= 0) {
526
+ appWidth = (allDayDifference * 100) - (!this.parent.activeViewOptions.allowOverlap ? 0 : widthAdjustment);
527
+ }
528
+ if (isNullOrUndefined(this.renderedAllDayEvents[parseInt(resource.toString(), 10)])) {
529
+ this.renderedAllDayEvents[parseInt(resource.toString(), 10)] = [];
530
+ }
531
+ this.renderedAllDayEvents[parseInt(resource.toString(), 10)].push(extend({}, record, null, true) as Record<string, any>);
532
+ const allDayRow: HTMLElement[] = [].slice.call(this.element.querySelector('.' + cls.ALLDAY_ROW_CLASS).children);
533
+ const wIndex: number = this.getDayIndex(dayIndex, resource, dayCount);
534
+ const eventWrapper: Element = this.element.querySelector('.' + cls.ALLDAY_APPOINTMENT_WRAPPER_CLASS +
535
+ ':nth-child(' + (wIndex + 1) + ')');
536
+ let appointmentElement: HTMLElement;
537
+ if (inline) {
538
+ appointmentElement = this.parent.inlineModule.createInlineAppointmentElement(eventObj);
539
+ } else {
540
+ appointmentElement = this.createAppointmentElement(eventObj, true, record.data as Record<string, any>, resource);
541
+ }
542
+ addClass([appointmentElement], cls.ALLDAY_APPOINTMENT_CLASS);
543
+ const eventData: Record<string, any> = extend({}, record.data, null, true);
544
+ eventObj.data = eventData;
545
+ const args: EventRenderedArgs = { data: eventObj, element: appointmentElement, cancel: false };
546
+ this.parent.trigger(events.eventRendered, args, (eventArgs: EventRenderedArgs) => {
547
+ if (!eventArgs.cancel) {
548
+ eventWrapper.appendChild(appointmentElement);
549
+ topValue += (allDayIndex === 0 ? cellTop : (cellTop + (allDayIndex * eventHeight))) + 1;
550
+ setStyleAttribute(appointmentElement, { 'width': appWidth + '%', 'top': formatUnit(topValue) });
551
+ if (allDayIndex > 1) {
552
+ this.moreEvents.push(appointmentElement);
553
+ for (let count: number = 0, length: number = allDayDifference; count < length; count++) {
554
+ this.createMoreIndicator(allDayRow, count, wIndex);
555
+ }
556
+ }
557
+ this.allDayElement[0].setAttribute('data-count', this.allDayLevel.toString());
558
+ const allDayRowHeight: number = ((!this.parent.uiStateValues.expand && this.allDayLevel > 2) ?
559
+ (3 * eventHeight) : ((this.allDayLevel + 1) * eventHeight)) + 4;
560
+ this.setAllDayRowHeight(allDayRowHeight);
561
+ this.addOrRemoveClass();
562
+ this.wireAppointmentEvents(appointmentElement, eventObj);
563
+ }
564
+ });
565
+ }
566
+ }
567
+ }
568
+
569
+ public renderNormalEvents(eventObj: Record<string, any>, dayIndex: number, resource: number, dayCount: number, inline?: boolean): void {
570
+ const record: Record<string, any> = this.isSpannedEvent(eventObj, dayIndex, resource);
571
+ const eStart: Date = record[this.fields.startTime] as Date;
572
+ const eEnd: Date = record[this.fields.endTime] as Date;
573
+ let appWidth: string = '0%'; const appLeft: string = '0%'; let topValue: number = 0;
574
+ const currentDate: Date =
575
+ util.resetTime(new Date(this.dateRender[parseInt(resource.toString(), 10)][parseInt(dayIndex.toString(), 10)].getTime()));
576
+ const schedule: { [key: string]: Date } = util.getStartEndHours(currentDate, this.startHour, this.endHour);
577
+ const isValidEvent: boolean = this.isValidEvent(eventObj, eStart, eEnd, schedule);
578
+ if ((eStart.getTime() < this.parent.minDate.getTime()) || (eEnd.getTime() > (util.addDays(this.parent.maxDate, 1)).getTime())) {
579
+ return;
580
+ }
581
+ if (eStart <= eEnd && isValidEvent && this.isWorkDayAvailable(resource, eStart)) {
582
+ const appHeight: number = record.isSpanned.isSameDuration ? this.cellHeight : this.getHeight(eStart, eEnd);
583
+ if (eStart.getTime() >= schedule.startHour.getTime()) {
584
+ topValue = this.getTopValue(eStart);
585
+ }
586
+ const appIndex: number = this.getOverlapIndex(record, dayIndex, false, resource);
587
+ record.Index = appIndex;
588
+ this.overlapList.push(record);
589
+ if (this.overlapList.length > 1) {
590
+ if (isNullOrUndefined(this.overlapEvents[parseInt(appIndex.toString(), 10)])) {
591
+ this.overlapEvents[parseInt(appIndex.toString(), 10)] = [];
592
+ }
593
+ this.overlapEvents[parseInt(appIndex.toString(), 10)].push(record);
594
+ } else {
595
+ this.overlapEvents = [];
596
+ this.overlapEvents.push([record]);
597
+ }
598
+ appWidth = this.getEventWidth();
599
+ const argsData: ElementData = {
600
+ index: appIndex, left: appLeft, width: appWidth,
601
+ day: dayCount, dayIndex: dayIndex, record: record, resource: resource
602
+ };
603
+ const tempData: Record<string, any> = this.adjustOverlapElements(argsData);
604
+ appWidth = (tempData.appWidth) as string;
605
+ if (isNullOrUndefined(this.renderedEvents[parseInt(resource.toString(), 10)])) {
606
+ this.renderedEvents[parseInt(resource.toString(), 10)] = [];
607
+ }
608
+ this.renderedEvents[parseInt(resource.toString(), 10)].push(extend({}, record, null, true) as Record<string, any>);
609
+ let appointmentElement: HTMLElement;
610
+ if (inline) {
611
+ appointmentElement = this.parent.inlineModule.createInlineAppointmentElement(eventObj);
612
+ } else {
613
+ appointmentElement = this.createAppointmentElement(eventObj, false, record.isSpanned as Record<string, any>, resource);
614
+ }
615
+ setStyleAttribute(appointmentElement, {
616
+ 'width': (this.parent.eventSettings.enableMaxHeight || !this.parent.activeViewOptions.allowOverlap ? '100%' : tempData.appWidth),
617
+ 'height': appHeight + 'px', 'top': topValue + 'px'
618
+ });
619
+ const iconHeight: number = appointmentElement.querySelectorAll('.' + cls.EVENT_INDICATOR_CLASS).length * 15;
620
+ const maxHeight: number = appHeight - 40 - iconHeight;
621
+ const subjectElement: HTMLElement = appointmentElement.querySelector('.' + cls.SUBJECT_CLASS) as HTMLElement;
622
+ if (!this.parent.isAdaptive && subjectElement) {
623
+ subjectElement.style.maxHeight = formatUnit(maxHeight);
624
+ }
625
+ const index: number = this.getDayIndex(dayIndex, resource, dayCount);
626
+ const eventData: Record<string, any> = {};
627
+ eventData[this.fields.startTime] = eventObj[this.fields.startTime];
628
+ eventData[this.fields.endTime] = eventObj[this.fields.endTime];
629
+ record.data = eventData;
630
+ this.appendEvent(record, appointmentElement, index, tempData.appLeft as string);
631
+ this.wireAppointmentEvents(appointmentElement, eventObj);
632
+ }
633
+ }
634
+
635
+ private getEventWidth(): string {
636
+ const width: number = this.parent.currentView === 'Day' ? 97 : 94;
637
+ const tempWidth: number = ((width - this.overlapEvents.length) / this.overlapEvents.length);
638
+ return (tempWidth < 0 ? 0 : tempWidth) + '%';
639
+ }
640
+
641
+ private getEventLeft(appWidth: string, index: number): string {
642
+ const tempLeft: number = (parseFloat(appWidth) + 1) * index;
643
+ return (tempLeft > 99 ? 99 : tempLeft) + '%';
644
+ }
645
+
646
+ private getStartEndHours(startEndTime: string): Date {
647
+ if (!isNullOrUndefined(startEndTime) && startEndTime !== '') {
648
+ const startEndDate: Date = new Date(2000, 0, 0, 0);
649
+ const timeString: string[] = startEndTime.split(':');
650
+ if (timeString.length === 2) {
651
+ startEndDate.setHours(parseInt(timeString[0], 10), parseInt(timeString[1], 10), 0);
652
+ }
653
+ return startEndDate;
654
+ }
655
+ return null;
656
+ }
657
+
658
+ public getTopValue(date: Date): number {
659
+ const startHour: Date = this.getStartEndHours(this.parent.activeViewOptions.startHour);
660
+ const diffInMinutes: number = ((date.getHours() - startHour.getHours()) * 60) + (date.getMinutes() - startHour.getMinutes());
661
+ return (this.parent.activeViewOptions.timeScale.enable) ? ((diffInMinutes * this.cellHeight * this.slotCount) / this.interval) : 0;
662
+ }
663
+
664
+ private getOverlapIndex(record: Record<string, any>, day: number, isAllDay: boolean, resource: number): number {
665
+ const fieldMapping: EventFieldsMapping = this.parent.eventFields;
666
+ let eventsList: Record<string, any>[] = []; let appIndex: number = -1; this.overlapEvents = [];
667
+ if (isAllDay) {
668
+ if (!isNullOrUndefined(this.renderedAllDayEvents[parseInt(resource.toString(), 10)])) {
669
+ const date: Date =
670
+ util.resetTime(new Date(this.dateRender[parseInt(resource.toString(), 10)][parseInt(day.toString(), 10)].getTime()));
671
+ eventsList = this.renderedAllDayEvents[parseInt(resource.toString(), 10)].filter((app: Record<string, any>) =>
672
+ util.resetTime(<Date>app[fieldMapping.startTime]).getTime() <= date.getTime() &&
673
+ util.resetTime(<Date>app[fieldMapping.endTime]).getTime() >= date.getTime());
674
+ if (this.parent.activeViewOptions.group.resources.length > 0) {
675
+ eventsList = this.filterEventsByResource(this.resources[parseInt(resource.toString(), 10)], eventsList);
676
+ }
677
+ }
678
+ } else {
679
+ const appointmentList: Record<string, any>[] = !isNullOrUndefined(this.renderedEvents[parseInt(resource.toString(), 10)]) ?
680
+ this.renderedEvents[parseInt(resource.toString(), 10)] : [];
681
+ let appointment: Record<string, any>[] = [];
682
+ const recordStart: Date = record[fieldMapping.startTime] as Date;
683
+ const recordEnd: Date = record[fieldMapping.endTime] as Date;
684
+ this.overlapList = appointmentList.filter((data: Record<string, any>) =>
685
+ (data[fieldMapping.endTime] > recordStart && data[fieldMapping.startTime] <= recordEnd) ||
686
+ (data[fieldMapping.startTime] >= recordEnd && data[fieldMapping.endTime] <= recordStart) ||
687
+ (data[fieldMapping.endTime].getTime() === data[fieldMapping.startTime].getTime() &&
688
+ data[fieldMapping.startTime].getTime() === recordStart.getTime() && data[fieldMapping.endTime] < recordEnd));
689
+ if (this.parent.activeViewOptions.group.resources.length > 0) {
690
+ this.overlapList = this.filterEventsByResource(this.resources[parseInt(resource.toString(), 10)], this.overlapList);
691
+ }
692
+ const queue: Record<string, any>[] = [];
693
+ this.overlapList.forEach((obj: Record<string, any>) => {
694
+ queue.push(obj);
695
+ let filterList: Record<string, any>[] = [];
696
+ const processedIds: Set<any> = new Set();
697
+ while (queue.length > 0) {
698
+ const currentObj: Record<string, any> = queue.shift() as Record<string, any>;
699
+ const overlaps: Record<string, any>[] = appointmentList.filter((data: Record<string, any>) => {
700
+ return data[fieldMapping.endTime] > currentObj[fieldMapping.startTime] &&
701
+ data[fieldMapping.startTime] <= currentObj[fieldMapping.endTime] &&
702
+ !processedIds.has(data[fieldMapping.id]);
703
+ });
704
+ overlaps.forEach((overlap: Record<string, any>) => {
705
+ filterList.push(overlap);
706
+ processedIds.add(overlap[fieldMapping.id]);
707
+ queue.push(overlap);
708
+ });
709
+ if (processedIds.size < appointmentList.length - 1) {
710
+ break;
711
+ }
712
+ }
713
+ if (this.parent.activeViewOptions.group.resources.length > 0) {
714
+ filterList = this.filterEventsByResource(this.resources[parseInt(resource.toString(), 10)], filterList);
715
+ }
716
+ const collection: Record<string, any>[] = filterList.filter((val: Record<string, any>) =>
717
+ this.overlapList.indexOf(val) === -1);
718
+ if (collection.length > 0) {
719
+ appointment = appointment.concat(collection);
720
+ }
721
+ });
722
+ for (let i: number = 0; i < appointment.length - 1; i++) {
723
+ for (let j: number = i + 1; j < appointment.length; j++) {
724
+ if (appointment[parseInt(i.toString(), 10)][fieldMapping.id] ===
725
+ appointment[parseInt(j.toString(), 10)][fieldMapping.id]) {
726
+ appointment.splice(j, 1); j--;
727
+ }
728
+ }
729
+ }
730
+ this.overlapList = this.overlapList.concat(appointment);
731
+ eventsList = this.overlapList;
732
+ for (const event of eventsList) {
733
+ const record: Record<string, any> = event;
734
+ const index: number = <number>record.Index;
735
+ if (isNullOrUndefined(this.overlapEvents[parseInt(index.toString(), 10)])) {
736
+ this.overlapEvents[parseInt(index.toString(), 10)] = [event];
737
+ } else {
738
+ this.overlapEvents[parseInt(index.toString(), 10)].push(event);
739
+ }
740
+ }
741
+ }
742
+ if (!isAllDay) {
743
+ eventsList = eventsList.filter((obj: Record<string, any>) => (obj[fieldMapping.startTime] === record[fieldMapping.startTime] &&
744
+ obj[fieldMapping.endTime] > record[fieldMapping.endTime] || obj[fieldMapping.endTime] > record[fieldMapping.startTime] &&
745
+ obj[fieldMapping.startTime] < record[fieldMapping.endTime] || obj[fieldMapping.endTime] === record[fieldMapping.startTime]
746
+ && obj[fieldMapping.startTime] === record[fieldMapping.endTime]) ||
747
+ ((obj[fieldMapping.startTime].getTime() === record[fieldMapping.startTime].getTime() &&
748
+ obj[fieldMapping.endTime].getTime() === record[fieldMapping.endTime].getTime())
749
+ || (obj[fieldMapping.startTime].getTime() === record[fieldMapping.startTime].getTime() &&
750
+ obj[fieldMapping.endTime].getTime() < record[fieldMapping.endTime].getTime() ||
751
+ obj[fieldMapping.endTime].getTime() > record[fieldMapping.endTime].getTime())));
752
+ }
753
+ if (eventsList.length > 0) {
754
+ const appLevel: number[] = eventsList.map((obj: Record<string, any>) => obj.Index) as number[];
755
+ appIndex = (appLevel.length > 0) ? this.getSmallestMissingNumber(appLevel) : 0;
756
+ }
757
+ return (appIndex === -1) ? 0 : appIndex;
758
+ }
759
+
760
+ private adjustOverlapElements(args: ElementData): Record<string, any> {
761
+ const data: Record<string, any> = { appWidth: args.width, appLeft: args.left };
762
+ for (let i: number = 0, length1: number = this.overlapEvents.length; i < length1; i++) {
763
+ if (!isNullOrUndefined(this.overlapEvents[parseInt(i.toString(), 10)])) {
764
+ for (let j: number = 0, length2: number = this.overlapEvents[parseInt(i.toString(), 10)].length; j < length2; j++) {
765
+ const dayCount: number = this.getDayIndex(args.dayIndex, args.resource, args.day);
766
+ const element: HTMLElement = this.element.querySelector('#e-appointment-wrapper-' + dayCount) as HTMLElement;
767
+ if (element && element.childElementCount > 0) {
768
+ const eleGuid: string =
769
+ (<Record<string, any>>this.overlapEvents[parseInt(i.toString(), 10)][parseInt(j.toString(), 10)]).Guid as string;
770
+ if (element.querySelectorAll('div[data-guid="' + eleGuid + '"]').length > 0 && eleGuid !== args.record.Guid) {
771
+ const apps: HTMLElement = element.querySelector('div[data-guid="' + eleGuid + '"]') as HTMLElement;
772
+ if (parseFloat(args.width) <= parseFloat(apps.style.width)) {
773
+ if (this.parent.enableRtl) {
774
+ apps.style.right = this.getEventLeft(args.width, i);
775
+ } else {
776
+ apps.style.left = this.getEventLeft(args.width, i);
777
+ }
778
+ apps.style.width = ((parseFloat(args.width))) + '%';
779
+ data.appWidth = apps.style.width;
780
+ } else {
781
+ data.appWidth = apps.style.width;
782
+ }
783
+ } else {
784
+ let appWidth: string = args.width;
785
+ if (isNullOrUndefined(this.overlapEvents[i - 1])) {
786
+ appWidth = this.getEventWidth();
787
+ }
788
+ data.appWidth = appWidth;
789
+ data.appLeft = this.getEventLeft(appWidth, args.index);
790
+ }
791
+ }
792
+ }
793
+ }
794
+ }
795
+ return data;
796
+ }
797
+
798
+ private setAllDayRowHeight(height: number): void {
799
+ const dateHeader: HTMLElement = (this.parent.element.querySelector('.' + cls.DATE_HEADER_WRAP_CLASS) as HTMLElement);
800
+ if (this.parent.height === 'auto' || !this.parent.enableAllDayScroll) {
801
+ addClass([dateHeader], cls.ALLDAY_APPOINTMENT_AUTO);
802
+ }
803
+ const allDayRow: HTMLElement = (this.parent.element.querySelector('.' + cls.ALLDAY_ROW_CLASS) as HTMLElement);
804
+ allDayRow.style.height = '';
805
+ if (this.parent.uiStateValues.expand && this.parent.height !== 'auto' && this.parent.enableAllDayScroll) {
806
+ allDayRow.style.height = (height / 12) + 'em';
807
+ this.parent.eventBase.allDayExpandScroll(dateHeader);
808
+ } else {
809
+ for (const element of this.allDayElement) {
810
+ (<HTMLElement>element).style.height = (height / 12) + 'em';
811
+ }
812
+ removeClass([dateHeader], cls.ALLDAY_APPOINTMENT_SCROLL);
813
+ }
814
+ }
815
+
816
+ private addOrRemoveClass(): void {
817
+ this.moreEvents.filter((element: HTMLElement) => {
818
+ if (!this.parent.uiStateValues.expand && this.allDayLevel > 2) {
819
+ addClass([element], cls.EVENT_COUNT_CLASS);
820
+ element.setAttribute('tabindex', '-1');
821
+ } else {
822
+ removeClass([element], cls.EVENT_COUNT_CLASS);
823
+ element.setAttribute('tabindex', '0');
824
+ }
825
+ });
826
+ const moreEventCount: HTMLElement = this.element.querySelector('.' + cls.ALLDAY_APPOINTMENT_SECTION_CLASS) as HTMLElement;
827
+ if (this.parent.uiStateValues.expand) {
828
+ removeClass([moreEventCount], cls.APPOINTMENT_ROW_EXPAND_CLASS);
829
+ addClass([moreEventCount], cls.APPOINTMENT_ROW_COLLAPSE_CLASS);
830
+ } else {
831
+ removeClass([moreEventCount], cls.APPOINTMENT_ROW_COLLAPSE_CLASS);
832
+ addClass([moreEventCount], cls.APPOINTMENT_ROW_EXPAND_CLASS);
833
+ }
834
+ if (this.allDayLevel > 2) {
835
+ removeClass([moreEventCount], cls.DISABLE_CLASS);
836
+ } else {
837
+ addClass([moreEventCount], cls.DISABLE_CLASS);
838
+ }
839
+ const countCell: Element[] = [].slice.call(this.element.querySelectorAll('.' + cls.ROW_COUNT_WRAPPER_CLASS));
840
+ countCell.forEach((element: Element) => {
841
+ if (!this.parent.uiStateValues.expand && this.allDayLevel > 2) {
842
+ removeClass([element], cls.DISABLE_CLASS);
843
+ } else {
844
+ addClass([element], cls.DISABLE_CLASS);
845
+ }
846
+ });
847
+ }
848
+
849
+ private getEventHeight(): number {
850
+ const eventElement: HTMLElement = createElement('div', { className: cls.APPOINTMENT_CLASS, styles: 'visibility:hidden' });
851
+ const eventWrapper: Element = this.element.querySelector('.' + cls.ALLDAY_APPOINTMENT_WRAPPER_CLASS + ':first-child');
852
+ eventWrapper.appendChild(eventElement);
853
+ const height: number = eventElement.offsetHeight;
854
+ remove(eventElement);
855
+ return height;
856
+ }
857
+
858
+ private rowExpandCollapse(): void {
859
+ const target: HTMLElement = this.element.querySelector('.' + cls.ALLDAY_APPOINTMENT_SECTION_CLASS) as HTMLElement;
860
+ this.parent.uiStateValues.expand = target.classList.contains(cls.APPOINTMENT_ROW_EXPAND_CLASS);
861
+ let rowHeight: number;
862
+ if (this.parent.uiStateValues.expand) {
863
+ target.setAttribute('title', this.parent.localeObj.getConstant('collapseAllDaySection'));
864
+ target.setAttribute('aria-label', this.parent.localeObj.getConstant('collapseAllDaySection'));
865
+ rowHeight = ((this.allDayLevel + 1) * this.getEventHeight()) + 4;
866
+ } else {
867
+ target.setAttribute('title', this.parent.localeObj.getConstant('expandAllDaySection'));
868
+ target.setAttribute('aria-label', this.parent.localeObj.getConstant('expandAllDaySection'));
869
+ rowHeight = (3 * this.getEventHeight()) + 4;
870
+ this.parent.element.querySelector('.' + cls.DATE_HEADER_WRAP_CLASS).scrollTop = 0;
871
+ }
872
+ this.setAllDayRowHeight(rowHeight);
873
+ this.animation.animate(this.allDayElement[0] as HTMLElement);
874
+ this.addOrRemoveClass();
875
+ this.animation.animate(target);
876
+ }
877
+
878
+ private animationUiUpdate(): void {
879
+ this.parent.notify(events.contentReady, {});
880
+ }
881
+
882
+ public destroy(): void {
883
+ if (!this.parent || this.parent && this.parent.isDestroyed) { return; }
884
+ this.removeEventListener();
885
+ this.allDayElement = null;
886
+ this.renderedAllDayEvents = null;
887
+ this.renderedEvents = null;
888
+ this.slotCount = null;
889
+ this.interval = null;
890
+ this.startHour = null;
891
+ this.endHour = null;
892
+ this.element = null;
893
+ this.fields = null;
894
+ this.animation = null;
895
+ super.destroy();
896
+ }
897
+
898
+ }