@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,766 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import { EventHandler, formatUnit, isNullOrUndefined, createElement, addClass, append, prepend, remove, extend } from '@syncfusion/ej2-base';
3
+ import { IRenderer, TdData, RenderCellEventArgs, CellTemplateArgs, NotifyEventArgs, CellClickEventArgs, CallbackFunction } from '../base/interface';
4
+ import { Schedule } from '../base/schedule';
5
+ import { ViewBase } from './view-base';
6
+ import { MonthEvent } from '../event-renderer/month';
7
+ import * as util from '../base/util';
8
+ import * as event from '../base/constant';
9
+ import * as cls from '../base/css-constant';
10
+ import { NavigationDirection } from '../base/type';
11
+
12
+ /**
13
+ * month view
14
+ */
15
+ export class Month extends ViewBase implements IRenderer {
16
+ public dayNameFormat: string = 'wide';
17
+ public viewClass: string = 'e-month-view';
18
+ public isInverseTableSelect: boolean = false;
19
+ private monthDates: { [key: string]: Date };
20
+ private monthEvent: MonthEvent = null;
21
+
22
+ constructor(parent: Schedule) {
23
+ super(parent);
24
+ this.monthDates = {};
25
+ }
26
+
27
+ public addEventListener(): void {
28
+ this.parent.on(event.scrollUiUpdate, this.onScrollUIUpdate, this);
29
+ this.parent.on(event.dataReady, this.onDataReady, this);
30
+ this.parent.on(event.cellClick, this.onCellClick, this);
31
+ }
32
+
33
+ public removeEventListener(): void {
34
+ if (this.parent) {
35
+ this.parent.off(event.scrollUiUpdate, this.onScrollUIUpdate);
36
+ this.parent.off(event.dataReady, this.onDataReady);
37
+ this.parent.off(event.cellClick, this.onCellClick);
38
+ }
39
+ }
40
+
41
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
42
+ public onDataReady(args: NotifyEventArgs): void {
43
+ this.monthEvent = new MonthEvent(this.parent);
44
+ this.monthEvent.renderAppointments();
45
+ this.parent.notify(event.eventsLoaded, {});
46
+ }
47
+
48
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
49
+ public onCellClick(event: CellClickEventArgs): void { /** */ }
50
+
51
+ public onContentScroll(e: Event): void {
52
+ if (!this.skipPersistenceSave) {
53
+ this.parent.removeNewEventElement();
54
+ this.parent.notify(event.virtualScroll, e);
55
+ this.scrollTopPanel(<HTMLElement>e.target);
56
+ this.scrollLeftPanel(<HTMLElement>e.target);
57
+ this.parent.uiStateValues.top = (e.target as HTMLElement).scrollTop;
58
+ this.parent.uiStateValues.left = (e.target as HTMLElement).scrollLeft;
59
+ this.setPersistence();
60
+ }
61
+ }
62
+
63
+ public scrollLeftPanel(target: HTMLElement): void {
64
+ const leftPanel: HTMLElement = this.getLeftPanelElement();
65
+ if (leftPanel) {
66
+ leftPanel.scrollTop = target.scrollTop;
67
+ }
68
+ }
69
+
70
+ public getLeftPanelElement(): HTMLElement {
71
+ return this.element.querySelector('.' + cls.WEEK_NUMBER_WRAPPER_CLASS) as HTMLElement;
72
+ }
73
+
74
+ public onScrollUIUpdate(args: NotifyEventArgs): void {
75
+ const headerHeight: number = this.getHeaderBarHeight();
76
+ const header: HTMLElement = this.getDatesHeaderElement();
77
+ const content: HTMLElement = this.getContentAreaElement();
78
+ const height: number = this.parent.element.offsetHeight - headerHeight - header.offsetHeight;
79
+ const leftPanel: HTMLElement = this.getLeftPanelElement();
80
+ if (this.parent.height !== 'auto') {
81
+ this.setContentHeight(content, leftPanel, height);
82
+ }
83
+ const scrollBarWidth: number = util.getScrollBarWidth();
84
+ (header.firstElementChild as HTMLElement).style[<any>args.cssProperties.rtlBorder] = '';
85
+ header.style[<any>args.cssProperties.rtlPadding] = '';
86
+ if (content.offsetWidth - content.clientWidth > 0) {
87
+ (<HTMLElement>header.firstElementChild).style[<any>args.cssProperties.border] = scrollBarWidth > 0 ? '1px' : '0px';
88
+ header.style[<any>args.cssProperties.padding] = scrollBarWidth > 0 ? scrollBarWidth - 1 + 'px' : '0px';
89
+ } else {
90
+ (<HTMLElement>header.firstElementChild).style[<any>args.cssProperties.border] = '';
91
+ header.style[<any>args.cssProperties.padding] = '';
92
+ }
93
+ this.setColWidth(content);
94
+ if (args.scrollPosition || !args.isPreventScrollUpdate && this.parent.currentView === 'TimelineMonth') {
95
+ const top: number = this.parent.currentView === 'TimelineMonth' ? this.parent.uiStateValues.top : args.scrollPosition.top;
96
+ if (leftPanel) {
97
+ leftPanel.scrollTop = top;
98
+ }
99
+ content.scrollTop = top;
100
+ if (this.parent.uiStateValues.isInitial) {
101
+ this.scrollToSelectedDate();
102
+ this.parent.uiStateValues.isInitial = false;
103
+ } else {
104
+ content.scrollLeft = this.parent.currentView === 'TimelineMonth' ? this.parent.uiStateValues.left :
105
+ args.scrollPosition.left;
106
+ }
107
+ }
108
+ this.retainScrollPosition();
109
+ }
110
+
111
+ private scrollToSelectedDate(): void {
112
+ const selectedDate: Date = new Date(this.parent.selectedDate);
113
+ selectedDate.setHours(0, 0, 0, 0);
114
+ const headerCell: HTMLElement = this.element.querySelector('.' + cls.HEADER_CELLS_CLASS + '[data-date="'
115
+ + selectedDate.getTime().toString() + '"]');
116
+ const content: HTMLElement = this.getContentAreaElement();
117
+ if (!isNullOrUndefined(headerCell)) {
118
+ content.scrollLeft = !this.parent.enableRtl ?
119
+ headerCell.offsetLeft : -(this.parent.getContentTable().offsetWidth - headerCell.offsetLeft - headerCell.offsetWidth);
120
+ } else {
121
+ content.scrollLeft = 0;
122
+ }
123
+ if (content.scrollLeft === 0 && this.parent.uiStateValues.isInitial) {
124
+ this.parent.uiStateValues.left = 0;
125
+ }
126
+ }
127
+
128
+ public setContentHeight(content: HTMLElement, leftPanelElement: HTMLElement, height: number): void {
129
+ content.style.height = 'auto';
130
+ if (this.parent.currentView === 'Month') {
131
+ content.style.height = formatUnit(height);
132
+ }
133
+ if (leftPanelElement) {
134
+ if (this.parent.currentView === 'MonthAgenda') {
135
+ height = (this.parent.activeViewOptions.interval > 1) ?
136
+ (<HTMLElement>this.getContentAreaElement().firstElementChild).offsetHeight :
137
+ (<HTMLElement>this.element.querySelector('.' + cls.CONTENT_TABLE_CLASS)).offsetHeight;
138
+ }
139
+ leftPanelElement.style.height = 'auto';
140
+ leftPanelElement.style.height = formatUnit(height - this.getScrollXIndent(content));
141
+ }
142
+ }
143
+
144
+ public generateColumnLevels(): TdData[][] {
145
+ let colLevels: TdData[][] = [];
146
+ const level: TdData[] = this.getDateSlots(this.renderDates, this.parent.activeViewOptions.workDays);
147
+ if (this.parent.activeViewOptions.group.resources.length > 0) {
148
+ colLevels = this.parent.resourceBase.generateResourceLevels(level);
149
+ if (this.parent.currentView === 'MonthAgenda') {
150
+ colLevels = [level];
151
+ }
152
+ if (this.parent.uiStateValues.isGroupAdaptive && this.parent.resourceBase.lastResourceLevel.length > 0) {
153
+ const resourceLevel: TdData = this.parent.resourceBase.lastResourceLevel[this.parent.uiStateValues.groupIndex];
154
+ let levels: TdData[] = this.getDateSlots(resourceLevel.renderDates, resourceLevel.workDays);
155
+ if (this.parent.activeViewOptions.group.byDate && this.parent.activeViewOptions.group.hideNonWorkingDays) {
156
+ const index: number = levels.findIndex((x: TdData, index: number) =>
157
+ index !== 0 && x.date.getDay() === levels[0].date.getDay());
158
+ levels = index > -1 ? levels.slice(0, index) : levels;
159
+ }
160
+ colLevels = [levels];
161
+ }
162
+ } else {
163
+ colLevels.push(level);
164
+ }
165
+ this.colLevels = colLevels;
166
+ return colLevels;
167
+ }
168
+
169
+ public getDateSlots(renderDates: Date[], workDays: number[]): TdData[] {
170
+ const count: number = this.parent.activeViewOptions.showWeekend ? util.WEEK_LENGTH : workDays.length;
171
+ const dateSlots: TdData[] = [];
172
+ const isCurrentMonth: boolean = this.isCurrentMonth(this.parent.selectedDate);
173
+ for (let col: number = 0; col < count; col++) {
174
+ const classList: string[] = [cls.HEADER_CELLS_CLASS];
175
+ const currentDateIndex: number[] = renderDates.slice(0, count).map((date: Date) => date.getDay());
176
+ if (isCurrentMonth && currentDateIndex.indexOf(this.parent.currentTimezoneDate.getDay()) === col) {
177
+ classList.push(cls.CURRENT_DAY_CLASS);
178
+ }
179
+ dateSlots.push({ date: renderDates[parseInt(col.toString(), 10)], type: 'monthDay', className: classList, colSpan: 1, workDays: workDays });
180
+ }
181
+ return dateSlots;
182
+ }
183
+
184
+ public getDayNameFormat(): string {
185
+ if (this.parent.isAdaptive || this.parent.activeViewOptions.group.resources.length > 0) {
186
+ return 'abbreviated';
187
+ }
188
+ return 'wide';
189
+ }
190
+
191
+ public renderLayout(type: string): void {
192
+ this.dayNameFormat = this.getDayNameFormat();
193
+ this.setPanel(createElement('div', { className: cls.TABLE_WRAP_CLASS }));
194
+ const clsList: string[] = [this.viewClass];
195
+ clsList.push(type);
196
+ if (this.parent.activeViewOptions.group.byDate) {
197
+ clsList.push('e-by-date');
198
+ if (this.parent.currentView !== 'Month') {
199
+ this.parent.activeViewOptions.group.hideNonWorkingDays = false;
200
+ }
201
+ }
202
+ if (this.parent.activeViewOptions.allowVirtualScrolling && !this.parent.uiStateValues.isGroupAdaptive) {
203
+ clsList.push(cls.VIRTUAL_SCROLL_CLASS);
204
+ }
205
+ if (this.parent.rowAutoHeight && this.parent.eventSettings.ignoreWhitespace) {
206
+ clsList.push(cls.IGNORE_WHITESPACE);
207
+ }
208
+ addClass([this.element], clsList);
209
+ this.renderPanel(type);
210
+ this.element.appendChild(this.createTableLayout(cls.OUTER_TABLE_CLASS) as HTMLElement);
211
+ this.element.querySelector('table').setAttribute('role', 'presentation');
212
+ this.colLevels = this.generateColumnLevels();
213
+ this.renderHeader();
214
+ this.renderContent();
215
+ const target: HTMLElement = (this.parent.currentView === 'MonthAgenda') ? this.parent.activeView.getPanel() : this.parent.element;
216
+ if (this.parent.uiStateValues.isGroupAdaptive && !target.querySelector('.' + cls.RESOURCE_TOOLBAR_CONTAINER)) {
217
+ this.renderResourceMobileLayout();
218
+ }
219
+ this.parent.notify(event.contentReady, {});
220
+ if (this.parent.uiStateValues.isCustomMonth) {
221
+ this.parent.uiStateValues.isCustomMonth = false;
222
+ }
223
+ }
224
+ public refreshHeader(): void {
225
+ remove(this.element.querySelector('tbody tr'));
226
+ this.renderHeader();
227
+ this.parent.notify(event.contentReady, {});
228
+ const dateHeader: HTMLElement = (this.element.querySelector('.' + cls.DATE_HEADER_WRAP_CLASS) as HTMLElement);
229
+ const contentWrapper: HTMLElement = (this.element.querySelector('.' + cls.CONTENT_WRAP_CLASS) as HTMLElement);
230
+ if (dateHeader) {
231
+ dateHeader.scrollLeft = this.parent.uiStateValues.left;
232
+ }
233
+ if (contentWrapper) {
234
+ contentWrapper.scrollLeft = this.parent.uiStateValues.left;
235
+ }
236
+ }
237
+
238
+ private wireCellEvents(element: Element): void {
239
+ EventHandler.add(element, 'mousedown', this.parent.workCellAction.cellMouseDown, this.parent.workCellAction);
240
+ EventHandler.add(element, 'click', this.parent.workCellAction.cellClick, this.parent.workCellAction);
241
+ if (!this.parent.isAdaptive) {
242
+ EventHandler.add(element, 'dblclick', this.parent.workCellAction.cellDblClick, this.parent.workCellAction);
243
+ }
244
+ }
245
+
246
+ public renderHeader(): void {
247
+ const tr: Element = createElement('tr');
248
+ this.renderLeftIndent(tr);
249
+ const dateTd: Element = createElement('td');
250
+ dateTd.appendChild(this.renderDatesHeader());
251
+ tr.appendChild(dateTd);
252
+ prepend([tr], this.element.querySelector('tbody'));
253
+ }
254
+
255
+ public renderLeftIndent(tr: Element): void {
256
+ if (this.parent.activeViewOptions.showWeekNumber) {
257
+ tr.appendChild(createElement('td', { className: 'e-left-indent' }));
258
+ }
259
+ }
260
+
261
+ public renderContent(): void {
262
+ if (this.parent.activeViewOptions.group.resources.length > 0) {
263
+ this.parent.resourceBase.renderedResources = <TdData[]>extend([], this.parent.resourceBase.lastResourceLevel, null, true);
264
+ }
265
+ const tr: Element = createElement('tr');
266
+ if (this.parent.activeViewOptions.showWeekNumber) {
267
+ tr.appendChild(this.renderWeekNumberContent());
268
+ }
269
+ const workTd: Element = createElement('td');
270
+ const levels: TdData[][] = this.colLevels.slice(0);
271
+ if (this.parent.virtualScrollModule) {
272
+ this.resetColLevels();
273
+ }
274
+ const wrap: Element = createElement('div', { className: cls.CONTENT_WRAP_CLASS });
275
+ const contentArea: Element = this.renderContentArea();
276
+ if (this.parent.currentView === 'Month') {
277
+ wrap.appendChild(contentArea);
278
+ } else {
279
+ const monthAgendaWrapper: HTMLElement = createElement('div', { className: cls.TABLE_CONTAINER_CLASS });
280
+ monthAgendaWrapper.appendChild(contentArea);
281
+ wrap.appendChild(monthAgendaWrapper);
282
+ }
283
+ EventHandler.add(wrap, 'scroll', this.onContentScroll, this);
284
+ workTd.appendChild(wrap);
285
+ tr.appendChild(workTd);
286
+ if (this.parent.virtualScrollModule) {
287
+ this.colLevels = levels;
288
+ this.parent.virtualScrollModule.renderVirtualTrack(wrap);
289
+ }
290
+ this.element.querySelector('tbody').appendChild(tr);
291
+ this.renderAppointmentContainer();
292
+ }
293
+
294
+ private renderWeekNumberContent(): HTMLElement {
295
+ const dateCol: Date[] = this.renderDates.map((date: Date) => new Date(+date));
296
+ const td: HTMLElement = createElement('td');
297
+ const contentWrapper: HTMLElement = createElement('div', { className: cls.WEEK_NUMBER_WRAPPER_CLASS });
298
+ td.appendChild(contentWrapper);
299
+ const contentWrapTable: HTMLElement = this.createTableLayout() as HTMLElement;
300
+ contentWrapper.appendChild(contentWrapTable);
301
+ const noOfDays: number = this.parent.activeViewOptions.showWeekend ? util.WEEK_LENGTH :
302
+ this.parent.activeViewOptions.workDays.length;
303
+ for (let i: number = 0, length: number = (this.renderDates.length / noOfDays); i < length; i++) {
304
+ const dates: Date[] = dateCol.splice(0, noOfDays);
305
+ const weekNumber: string = this.parent.getWeekNumberContent(dates);
306
+ contentWrapTable.querySelector('tbody').appendChild(this.createWeekNumberElement(weekNumber));
307
+ }
308
+ return td;
309
+ }
310
+
311
+ public renderAppointmentContainer(): void {
312
+ //Here needs to render mobile view appointment details on selected date
313
+ }
314
+
315
+ public renderDatesHeader(): Element {
316
+ const container: Element = createElement('div', { className: cls.DATE_HEADER_CONTAINER_CLASS });
317
+ const wrap: Element = createElement('div', { className: cls.DATE_HEADER_WRAP_CLASS });
318
+ container.appendChild(wrap);
319
+ const table: Element = this.createTableLayout();
320
+ if (this.parent.currentView === 'Month') {
321
+ const thead: Element = createElement('thead');
322
+ thead.appendChild(createElement('tr'));
323
+ prepend([thead], table);
324
+ }
325
+ this.createColGroup(table, this.colLevels[this.colLevels.length - 1]);
326
+ const trEle: Element = createElement('tr');
327
+ for (let i: number = 0; i < this.colLevels.length; i++) {
328
+ const level: TdData[] = this.colLevels[parseInt(i.toString(), 10)];
329
+ const ntr: Element = trEle.cloneNode() as Element;
330
+ for (let j: number = 0; j < level.length; j++) {
331
+ const td: TdData = level[parseInt(j.toString(), 10)];
332
+ ntr.appendChild(this.createHeaderCell(td));
333
+ }
334
+ table.querySelector('tbody').appendChild(ntr);
335
+ }
336
+ wrap.appendChild(table);
337
+ return container;
338
+ }
339
+
340
+ private createHeaderCell(td: TdData): Element {
341
+ const tdEle: Element = createElement('td');
342
+ this.addAttributes(td, tdEle);
343
+ if (td.type === 'monthDay') {
344
+ const ele: Element = createElement(
345
+ 'span', { innerHTML: util.capitalizeFirstWord(this.parent.getDayNames(this.dayNameFormat)[td.date.getDay()], 'single') });
346
+ tdEle.appendChild(ele);
347
+ }
348
+ if (td.type === 'resourceHeader') {
349
+ this.setResourceHeaderContent(tdEle, td);
350
+ }
351
+ if (td.type === 'dateHeader') {
352
+ addClass([tdEle], cls.DATE_HEADER_CLASS);
353
+ tdEle.setAttribute('data-date', td.date.getTime().toString());
354
+ if (this.parent.activeViewOptions.dateHeaderTemplate) {
355
+ const cellArgs: CellTemplateArgs = { date: td.date, type: td.type };
356
+ const elementId: string = this.parent.element.id + '_';
357
+ const viewName: string = this.parent.activeViewOptions.dateHeaderTemplateName;
358
+ const templateId: string = elementId + viewName + 'dateHeaderTemplate';
359
+ const dateTemplate: HTMLElement[] = [].slice.call(
360
+ this.parent.getDateHeaderTemplate()(cellArgs, this.parent, 'dateHeaderTemplate', templateId,
361
+ false, undefined, undefined, this.parent.root));
362
+ if (dateTemplate && dateTemplate.length) {
363
+ append(dateTemplate, tdEle);
364
+ }
365
+ } else {
366
+ const ele: Element = createElement('span', { className: cls.NAVIGATE_CLASS });
367
+ const skeleton: string = 'full';
368
+ const title: string =
369
+ this.parent.globalize.formatDate(td.date, { skeleton: skeleton, calendar: this.parent.getCalendarMode() });
370
+ ele.setAttribute('title', util.capitalizeFirstWord(title, 'multiple'));
371
+ const innerText: string =
372
+ (this.parent.calendarUtil.isMonthStart(td.date) && !this.isCurrentDate(td.date) && !this.parent.isAdaptive) ?
373
+ this.parent.globalize.formatDate(td.date, { format: 'MMM d', calendar: this.parent.getCalendarMode() }) :
374
+ this.parent.globalize.formatDate(td.date, { skeleton: 'd', calendar: this.parent.getCalendarMode() });
375
+ ele.innerHTML = util.capitalizeFirstWord(innerText, 'single');
376
+ tdEle.appendChild(ele);
377
+ }
378
+ this.wireCellEvents(tdEle);
379
+ }
380
+ const args: RenderCellEventArgs = { elementType: td.type, element: tdEle, date: td.date, groupIndex: td.groupIndex };
381
+ this.parent.trigger(event.renderCell, args);
382
+ return tdEle;
383
+ }
384
+
385
+ public getContentSlots(): TdData[][] {
386
+ if (!(this.colLevels[this.colLevels.length - 1] && this.colLevels[this.colLevels.length - 1][0])) {
387
+ return [];
388
+ }
389
+ const slotDatas: TdData[][] = [];
390
+ const prepareSlots: CallbackFunction = (rowIndex: number, renderDate: Date, resData: TdData, classList?: string[]) => {
391
+ const data: TdData = {
392
+ date: new Date(+renderDate), groupIndex: resData.groupIndex, workDays: resData.workDays,
393
+ type: 'monthCells', className: classList || [cls.WORK_CELLS_CLASS]
394
+ };
395
+ if (!slotDatas[parseInt(rowIndex.toString(), 10)]) {
396
+ slotDatas[parseInt(rowIndex.toString(), 10)] = [];
397
+ }
398
+ slotDatas[parseInt(rowIndex.toString(), 10)].push(data);
399
+ };
400
+ const includeResource: boolean = this.parent.currentView !== 'MonthAgenda' &&
401
+ this.parent.activeViewOptions.group.resources.length > 0;
402
+ if (includeResource && !this.parent.uiStateValues.isGroupAdaptive && !this.parent.activeViewOptions.group.byDate) {
403
+ for (const res of this.colLevels[this.colLevels.length - 2]) {
404
+ const dates: Date[] = res.renderDates.map((date: Date) => new Date(+date));
405
+ const count: number = this.parent.activeViewOptions.showWeekend ? util.WEEK_LENGTH : res.workDays.length;
406
+ for (let i: number = 0; i < (res.renderDates.length / count); i++) {
407
+ const colDates: Date[] = dates.splice(0, count);
408
+ for (const colDate of colDates) {
409
+ prepareSlots(i, colDate, res);
410
+ }
411
+ }
412
+ }
413
+ } else {
414
+ const dates: Date[] = this.renderDates.map((date: Date) => new Date(+date));
415
+ const count: number = this.parent.activeViewOptions.showWeekend ? util.WEEK_LENGTH :
416
+ this.parent.activeViewOptions.workDays.length;
417
+ const level: TdData[] = this.colLevels.slice(0, 1)[0];
418
+ const startIndex: number = this.renderDates.map(Number).indexOf(+level[0].date);
419
+ for (let i: number = 0; i < (this.renderDates.length / count); i++) {
420
+ const colDates: Date[] = dates.splice(0, count);
421
+ let k: number = startIndex;
422
+ for (let j: number = startIndex; j < (this.colLevels[0].length + startIndex) && j < colDates.length; j++) {
423
+ const colDate: Date = colDates[parseInt(k.toString(), 10)];
424
+ k++;
425
+ if (includeResource) {
426
+ const lastRow: TdData[] = this.colLevels[(this.colLevels.length - 1)];
427
+ const rowCount: number = lastRow.length / count;
428
+ let resourcesTd: TdData[] = lastRow.slice(0, rowCount);
429
+ if (this.parent.activeViewOptions.group.hideNonWorkingDays) {
430
+ resourcesTd = lastRow.filter((x: TdData) => x.date.getDay() === colDate.getDay());
431
+ if (resourcesTd.length === 0) {
432
+ j = j - 1;
433
+ continue;
434
+ }
435
+ }
436
+ for (let resIndex: number = 0; resIndex < resourcesTd.length; resIndex++) {
437
+ let clsList: string[];
438
+ if (resIndex !== 0) {
439
+ clsList = [cls.WORK_CELLS_CLASS, cls.DISABLE_DATE];
440
+ }
441
+ prepareSlots(i, colDate, resourcesTd[parseInt(resIndex.toString(), 10)], clsList);
442
+ }
443
+ } else {
444
+ prepareSlots(i, colDate, this.colLevels[this.colLevels.length - 1][0]);
445
+ }
446
+ }
447
+ }
448
+ }
449
+ return slotDatas;
450
+ }
451
+
452
+ public updateClassList(data: TdData): void {
453
+ if (!this.isCustomMonth() && this.isOtherMonth(data.date)) {
454
+ data.className.push(cls.OTHERMONTH_CLASS);
455
+ }
456
+ if (!this.parent.isMinMaxDate(data.date)) {
457
+ data.className.push(cls.DISABLE_DATES);
458
+ }
459
+ this.updateSelectedCellClass(data);
460
+ }
461
+
462
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
463
+ public updateSelectedCellClass(data: TdData): void {
464
+ return;
465
+ }
466
+
467
+ private isOtherMonth(date: Date): boolean {
468
+ return date.getTime() < this.monthDates.start.getTime() || date.getTime() > this.monthDates.end.getTime();
469
+ }
470
+
471
+ public renderContentArea(): Element {
472
+ const tbl: Element = this.createTableLayout(cls.CONTENT_TABLE_CLASS);
473
+ this.setAriaAttributes(tbl);
474
+ this.addAutoHeightClass(tbl);
475
+ if (this.parent.currentView === 'TimelineMonth') {
476
+ this.createColGroup(tbl, this.colLevels[this.colLevels.length - 1]);
477
+ }
478
+ const monthDate: Date = new Date(this.parent.selectedDate.getTime());
479
+ this.monthDates = {
480
+ start: this.parent.calendarUtil.firstDateOfMonth(monthDate),
481
+ end: this.parent.calendarUtil.lastDateOfMonth(util.addMonths(monthDate, this.parent.activeViewOptions.interval - 1))
482
+ };
483
+ const tBody: Element = tbl.querySelector('tbody');
484
+ append(this.getContentRows(), tBody);
485
+ this.wireCellEvents(tBody);
486
+ return tbl;
487
+ }
488
+
489
+ public getContentRows(): Element[] {
490
+ const trows: Element[] = [];
491
+ const tr: Element = createElement('tr');
492
+ const td: Element = createElement('td');
493
+ const slotDatas: TdData[][] = this.getContentSlots();
494
+ const isTimeline: boolean = this.parent.currentView === 'TimelineMonth';
495
+ const existingGroupIndices: number[] = isTimeline ? this.getGroupIndices() : [];
496
+ for (let row: number = 0; row < slotDatas.length; row++) {
497
+ if (existingGroupIndices.length > 0 &&
498
+ existingGroupIndices.indexOf(slotDatas[parseInt(row.toString(), 10)][0].groupIndex) > -1) {
499
+ continue;
500
+ }
501
+ const ntr: Element = tr.cloneNode() as Element;
502
+ for (let col: number = 0; col < slotDatas[parseInt(row.toString(), 10)].length; col++) {
503
+ const ntd: Element = this.createContentTd(slotDatas[parseInt(row.toString(), 10)][parseInt(col.toString(), 10)], td);
504
+ ntr.appendChild(ntd);
505
+ }
506
+ trows.push(ntr);
507
+ }
508
+ return trows;
509
+ }
510
+
511
+ public createContentTd(data: TdData, td: Element): Element {
512
+ const ntd: Element = td.cloneNode() as Element;
513
+ if (data.colSpan) { ntd.setAttribute('colspan', data.colSpan.toString()); }
514
+ this.updateClassList(data);
515
+ let type: string = data.type;
516
+ if (data.className.indexOf(cls.RESOURCE_PARENT_CLASS) !== -1) {
517
+ data.className.push(cls.RESOURCE_GROUP_CELLS_CLASS);
518
+ type = 'resourceGroupCells';
519
+ }
520
+ if (this.parent.workHours.highlight && this.isWorkDay(data.date, data.workDays)) {
521
+ data.className.push(cls.WORKDAY_CLASS);
522
+ }
523
+ if (this.isCurrentDate(data.date)) {
524
+ data.className.push(cls.CURRENTDATE_CLASS);
525
+ }
526
+ addClass([ntd], data.className);
527
+ ntd.setAttribute('data-date', data.date.getTime().toString());
528
+ if (!isNullOrUndefined(data.groupIndex) || this.parent.uiStateValues.isGroupAdaptive) {
529
+ const groupIndex: number = this.parent.uiStateValues.isGroupAdaptive ? this.parent.uiStateValues.groupIndex :
530
+ data.groupIndex;
531
+ ntd.setAttribute('data-group-index', '' + groupIndex);
532
+ }
533
+ this.renderDateHeaderElement(data, ntd);
534
+ if (this.parent.activeViewOptions.cellTemplate) {
535
+ const args: CellTemplateArgs = { date: data.date, type: type, groupIndex: data.groupIndex };
536
+ const scheduleId: string = this.parent.element.id + '_';
537
+ const viewName: string = this.parent.activeViewOptions.cellTemplateName;
538
+ const templateId: string = scheduleId + viewName + 'cellTemplate';
539
+ const cellTemplate: HTMLElement[] = [].slice.call(
540
+ this.parent.getCellTemplate()(args, this.parent, 'cellTemplate', templateId,
541
+ false, undefined, undefined, this.parent.root));
542
+ append(cellTemplate, ntd);
543
+ }
544
+ const args: RenderCellEventArgs = { elementType: type, element: ntd, date: data.date, groupIndex: data.groupIndex };
545
+ this.parent.trigger(event.renderCell, args);
546
+ return ntd;
547
+ }
548
+
549
+ private renderDateHeaderElement(data: TdData, ntd: Element): void {
550
+ if (this.parent.currentView === 'TimelineMonth') {
551
+ return;
552
+ }
553
+ const dateHeader: Element = createElement('div', { className: cls.DATE_HEADER_CLASS });
554
+ if (this.parent.activeViewOptions.cellHeaderTemplate) {
555
+ const args: CellTemplateArgs = { date: data.date, type: data.type, groupIndex: data.groupIndex };
556
+ const scheduleId: string = this.parent.element.id + '_';
557
+ const viewName: string = this.parent.activeViewOptions.cellHeaderTemplateName;
558
+ const templateId: string = scheduleId + viewName + 'cellHeaderTemplate';
559
+ const cellHeaderTemplate: HTMLElement[] = [].slice.call(
560
+ this.parent.getCellHeaderTemplate()(args, this.parent, 'cellHeaderTemplate', templateId, false,
561
+ undefined, undefined, this.parent.root));
562
+ append(cellHeaderTemplate, dateHeader);
563
+ } else {
564
+ const innerText: string =
565
+ (this.parent.calendarUtil.isMonthStart(data.date) && !this.isCurrentDate(data.date) && !this.parent.isAdaptive) ?
566
+ this.parent.globalize.formatDate(data.date, { format: 'MMM d', calendar: this.parent.getCalendarMode() }) :
567
+ this.parent.globalize.formatDate(data.date, { skeleton: 'd', calendar: this.parent.getCalendarMode() });
568
+ dateHeader.innerHTML = util.capitalizeFirstWord(innerText, 'single');
569
+ }
570
+ ntd.appendChild(dateHeader);
571
+ if (this.getModuleName() === 'month') {
572
+ addClass([dateHeader], cls.NAVIGATE_CLASS);
573
+ const skeleton: string = 'full';
574
+ const announcementText: string =
575
+ this.parent.globalize.formatDate(data.date, { skeleton: skeleton, calendar: this.parent.getCalendarMode() });
576
+ ntd.setAttribute('aria-label', announcementText);
577
+ }
578
+ }
579
+
580
+ public getMonthStart(currentDate: Date): Date {
581
+ const useDisplayDate: boolean = this.parent.currentView === 'Month' && !isNullOrUndefined(
582
+ this.parent.activeViewOptions.displayDate) && !(this.parent.uiStateValues.isSwipeScroll) &&
583
+ (this.parent.uiStateValues.isCustomMonth || this.isCustomRange());
584
+ const date: Date = useDisplayDate ? this.parent.activeViewOptions.displayDate : !(this.parent.uiStateValues.isCustomMonth ||
585
+ (!this.parent.uiStateValues.isSwipeScroll && this.isCustomRange())) && this.isCustomMonth() ? currentDate :
586
+ this.parent.calendarUtil.firstDateOfMonth(currentDate);
587
+ const monthStart: Date = util.getWeekFirstDate(date, this.parent.activeViewOptions.firstDayOfWeek);
588
+ return new Date(monthStart.getFullYear(), monthStart.getMonth(), monthStart.getDate());
589
+ }
590
+
591
+ public getMonthEnd(currentDate: Date): Date {
592
+ if (this.isCustomMonth()) {
593
+ const start: Date = this.getMonthStart(currentDate);
594
+ const numberOfDays: number = util.WEEK_LENGTH * (this.parent.activeViewOptions.numberOfWeeks > 0 ?
595
+ this.parent.activeViewOptions.numberOfWeeks : util.DEFAULT_WEEKS);
596
+ return util.addDays(start, (numberOfDays - 1));
597
+ } else {
598
+ const endDate: Date = util.addMonths(currentDate, this.parent.activeViewOptions.interval - 1);
599
+ const lastWeekOfMonth: Date =
600
+ util.getWeekFirstDate(this.parent.calendarUtil.lastDateOfMonth(endDate), this.parent.activeViewOptions.firstDayOfWeek);
601
+ return util.addDays(lastWeekOfMonth, util.WEEK_LENGTH - 1);
602
+ }
603
+ }
604
+
605
+ private isCustomRange(): boolean {
606
+ const dates: Date[] = this.parent.getCurrentViewDates();
607
+ if (dates && dates.length > 0) {
608
+ const selectedTime: number = util.resetTime(this.parent.selectedDate).getTime();
609
+ const weekFirstDate: Date = util.getWeekFirstDate(dates[dates.length - 1], this.parent.activeViewOptions.firstDayOfWeek);
610
+ return !(selectedTime >= util.getWeekFirstDate(dates[0], this.parent.activeViewOptions.firstDayOfWeek).getTime() &&
611
+ selectedTime <= util.addDays(weekFirstDate, 6).getTime());
612
+ }
613
+ return false;
614
+ }
615
+
616
+ public getRenderDates(workDays?: number[], selectedDate: Date = this.parent.selectedDate): Date[] {
617
+ const renderDates: Date[] = [];
618
+ const currentDate: Date = util.resetTime(selectedDate);
619
+ let start: Date = this.getMonthStart(currentDate);
620
+ const monthEnd: Date = this.getMonthEnd(currentDate);
621
+ do {
622
+ if (this.parent.activeViewOptions.showWeekend) {
623
+ renderDates.push(start);
624
+ } else {
625
+ if (this.isWorkDay(start, workDays)) {
626
+ renderDates.push(start);
627
+ }
628
+ }
629
+ start = util.addDays(start, 1);
630
+ if (start.getHours() > 0) {
631
+ start = util.resetTime(start);
632
+ }
633
+ } while (start.getTime() <= monthEnd.getTime());
634
+ if (!workDays) {
635
+ this.renderDates = renderDates;
636
+ }
637
+ if (this.parent.headerModule) {
638
+ this.parent.headerModule.previousNextIconHandler();
639
+ }
640
+ return renderDates;
641
+ }
642
+
643
+ public getNextPreviousDate(type: NavigationDirection): Date {
644
+ if (this.isCustomMonth()) {
645
+ const dates: Date[] = this.parent.getCurrentViewDates();
646
+ const date: Date = util.getWeekFirstDate(type === 'Next' ? dates[dates.length - 1]
647
+ : dates[0], this.parent.activeViewOptions.firstDayOfWeek);
648
+ return util.addDays(date, type === 'Next' ? util.WEEK_LENGTH : -(this.parent.activeViewOptions.numberOfWeeks > 0 ?
649
+ this.parent.activeViewOptions.numberOfWeeks : util.DEFAULT_WEEKS) * util.WEEK_LENGTH);
650
+ } else {
651
+ return util.addMonths(this.parent.selectedDate, ((type === 'Next' ? 1 : -1) * this.parent.activeViewOptions.interval));
652
+ }
653
+ }
654
+
655
+ public getStartDate(): Date {
656
+ return this.getMonthStart(this.parent.selectedDate);
657
+ }
658
+
659
+ public getEndDate(): Date {
660
+ return this.getMonthEnd(this.parent.selectedDate);
661
+ }
662
+
663
+ public getEndDateFromStartDate(start: Date): Date {
664
+ return util.addDays(new Date(start.getTime()), 1);
665
+ }
666
+
667
+ public getDateRangeText(startDate: Date = this.parent.selectedDate, dateCollection: Date[] = null): string {
668
+ if (this.parent.isAdaptive || isNullOrUndefined(this.parent.activeViewOptions.dateFormat)) {
669
+ const maxNumberOfDaysPerWeek: number = 7;
670
+ startDate = !isNullOrUndefined(dateCollection) && dateCollection.length > maxNumberOfDaysPerWeek - 1
671
+ ? dateCollection[maxNumberOfDaysPerWeek - 1] : startDate;
672
+ let endDate: Date;
673
+ let updateCustomRange: boolean = false;
674
+
675
+ if (this.isCustomMonth()) {
676
+ const dates: Date[] = !isNullOrUndefined(dateCollection) && dateCollection.length > 0 ? dateCollection :
677
+ this.parent.getCurrentViewDates();
678
+ updateCustomRange = dates[0].getMonth() !== dates[dates.length - 1].getMonth() ||
679
+ dates[0].getFullYear() !== dates[dates.length - 1].getFullYear();
680
+ if (updateCustomRange) {
681
+ startDate = dates[0];
682
+ endDate = dates[dates.length - 1];
683
+ }
684
+ }
685
+
686
+ const isUpdateDateRange: boolean = (this.parent.currentView !== 'Month' || !this.isCustomMonth());
687
+ if (this.parent.activeViewOptions.interval > 1 && isUpdateDateRange || updateCustomRange) {
688
+ endDate = endDate ? endDate : util.addMonths(util.lastDateOfMonth(startDate), this.parent.activeViewOptions.interval - 1);
689
+ if (startDate.getFullYear() === endDate.getFullYear()) {
690
+ const monthNames: string = (this.parent.globalize.formatDate(
691
+ startDate, { format: 'MMMM', calendar: this.parent.getCalendarMode() })) + ' - ' +
692
+ (this.parent.globalize.formatDate(endDate, { format: 'MMMM ', calendar: this.parent.getCalendarMode() })) +
693
+ this.parent.globalize.formatDate(endDate, { skeleton: 'y', calendar: this.parent.getCalendarMode() });
694
+ return util.capitalizeFirstWord(monthNames, 'single');
695
+ }
696
+ const text: string = (this.parent.globalize.formatDate(
697
+ startDate, { format: 'MMMM', calendar: this.parent.getCalendarMode() })) + ' ' +
698
+ startDate.getFullYear() + ' - ' +
699
+ this.parent.globalize.formatDate(endDate, { format: 'MMMM ', calendar: this.parent.getCalendarMode() }) +
700
+ this.parent.globalize.formatDate(endDate, { skeleton: 'y', calendar: this.parent.getCalendarMode() });
701
+ return util.capitalizeFirstWord(text, 'single');
702
+ }
703
+ const format: string = (this.parent.activeViewOptions.dateFormat) ? this.parent.activeViewOptions.dateFormat : 'MMMM y';
704
+ return util.capitalizeFirstWord(
705
+ this.parent.globalize.formatDate(startDate, { format: format, calendar: this.parent.getCalendarMode() }), 'single');
706
+ }
707
+ return this.formatDateRange(!isNullOrUndefined(dateCollection) && dateCollection.length > 0 ? dateCollection[0] :
708
+ this.parent.selectedDate);
709
+ }
710
+
711
+ public getLabelText(view: string): string {
712
+ const viewStr: string = view.charAt(0).toLowerCase() + view.substring(1);
713
+ return this.formatViewLabel(viewStr, this.getStartDate(), this.getEndDate());
714
+ }
715
+
716
+ private createWeekNumberElement(text?: string): HTMLElement {
717
+ const tr: HTMLElement = createElement('tr');
718
+ const td: HTMLElement = createElement('td', {
719
+ className: cls.WEEK_NUMBER_CLASS,
720
+ attrs: { 'title': (text ? this.parent.localeObj.getConstant('week') + ' ' + text : '') },
721
+ innerHTML: (text || '')
722
+ });
723
+ tr.appendChild(td);
724
+ const args: RenderCellEventArgs = { elementType: 'weekNumberCell', element: td };
725
+ this.parent.trigger(event.renderCell, args);
726
+ return tr;
727
+ }
728
+
729
+ public unWireEvents(): void {
730
+ const contentScrollableEle: Element = this.element.querySelector('.' + cls.CONTENT_WRAP_CLASS);
731
+ if (contentScrollableEle) {
732
+ EventHandler.remove(contentScrollableEle, 'scroll', this.onContentScroll);
733
+ }
734
+ }
735
+
736
+ private isCustomMonth(): boolean {
737
+ return this.parent.currentView === 'Month' &&
738
+ (!isNullOrUndefined(this.parent.activeViewOptions.displayDate) || this.parent.activeViewOptions.numberOfWeeks > 0);
739
+ }
740
+
741
+ protected getModuleName(): string {
742
+ return 'month';
743
+ }
744
+
745
+ public destroy(): void {
746
+ if (!this.parent || this.parent && this.parent.isDestroyed) {
747
+ this.parent = null;
748
+ return;
749
+ }
750
+ if (this.element) {
751
+ if (this.monthEvent) {
752
+ this.monthEvent.destroy();
753
+ this.monthEvent = null;
754
+ }
755
+ this.unWireEvents();
756
+ if (this.parent.resourceBase) {
757
+ this.parent.resourceBase.destroy();
758
+ }
759
+ if (this.parent.scheduleTouchModule) {
760
+ this.parent.scheduleTouchModule.resetValues();
761
+ }
762
+ super.destroy();
763
+ }
764
+ }
765
+
766
+ }