@syncfusion/ej2-schedule 31.1.17 → 31.1.20

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 (167) 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 +1 -1
  5. package/dist/es6/ej2-schedule.es2015.js.map +1 -1
  6. package/dist/es6/ej2-schedule.es5.js +1 -1
  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/package.json +17 -52
  12. package/src/schedule/event-renderer/event-base.js +1 -1
  13. package/styles/bootstrap4-lite.css +8 -0
  14. package/styles/bootstrap4.css +8 -0
  15. package/styles/recurrence-editor/bootstrap4.css +8 -0
  16. package/styles/schedule/bootstrap4.css +8 -0
  17. package/dist/ts/common/calendar-util.d.ts +0 -92
  18. package/dist/ts/common/calendar-util.ts +0 -261
  19. package/dist/ts/common/index.d.ts +0 -4
  20. package/dist/ts/common/index.ts +0 -4
  21. package/dist/ts/components.d.ts +0 -5
  22. package/dist/ts/components.ts +0 -5
  23. package/dist/ts/index.d.ts +0 -6
  24. package/dist/ts/index.ts +0 -7
  25. package/dist/ts/recurrence-editor/date-generator.d.ts +0 -76
  26. package/dist/ts/recurrence-editor/date-generator.ts +0 -1699
  27. package/dist/ts/recurrence-editor/index.d.ts +0 -6
  28. package/dist/ts/recurrence-editor/index.ts +0 -6
  29. package/dist/ts/recurrence-editor/recurrence-editor-model.d.ts +0 -112
  30. package/dist/ts/recurrence-editor/recurrence-editor.d.ts +0 -245
  31. package/dist/ts/recurrence-editor/recurrence-editor.ts +0 -1257
  32. package/dist/ts/schedule/actions/action-base.d.ts +0 -44
  33. package/dist/ts/schedule/actions/action-base.ts +0 -493
  34. package/dist/ts/schedule/actions/crud.d.ts +0 -41
  35. package/dist/ts/schedule/actions/crud.ts +0 -784
  36. package/dist/ts/schedule/actions/data.d.ts +0 -63
  37. package/dist/ts/schedule/actions/data.ts +0 -128
  38. package/dist/ts/schedule/actions/drag.d.ts +0 -75
  39. package/dist/ts/schedule/actions/drag.ts +0 -1401
  40. package/dist/ts/schedule/actions/keyboard.d.ts +0 -100
  41. package/dist/ts/schedule/actions/keyboard.ts +0 -1435
  42. package/dist/ts/schedule/actions/resize.d.ts +0 -27
  43. package/dist/ts/schedule/actions/resize.ts +0 -602
  44. package/dist/ts/schedule/actions/scroll.d.ts +0 -69
  45. package/dist/ts/schedule/actions/scroll.ts +0 -105
  46. package/dist/ts/schedule/actions/touch.d.ts +0 -32
  47. package/dist/ts/schedule/actions/touch.ts +0 -314
  48. package/dist/ts/schedule/actions/virtual-scroll.d.ts +0 -55
  49. package/dist/ts/schedule/actions/virtual-scroll.ts +0 -596
  50. package/dist/ts/schedule/actions/work-cells.d.ts +0 -14
  51. package/dist/ts/schedule/actions/work-cells.ts +0 -151
  52. package/dist/ts/schedule/base/constant.d.ts +0 -102
  53. package/dist/ts/schedule/base/constant.ts +0 -103
  54. package/dist/ts/schedule/base/css-constant.d.ts +0 -475
  55. package/dist/ts/schedule/base/css-constant.ts +0 -475
  56. package/dist/ts/schedule/base/interface.d.ts +0 -673
  57. package/dist/ts/schedule/base/interface.ts +0 -738
  58. package/dist/ts/schedule/base/resource.d.ts +0 -59
  59. package/dist/ts/schedule/base/resource.ts +0 -1091
  60. package/dist/ts/schedule/base/schedule-model.d.ts +0 -930
  61. package/dist/ts/schedule/base/schedule.d.ts +0 -1967
  62. package/dist/ts/schedule/base/schedule.ts +0 -4221
  63. package/dist/ts/schedule/base/type.d.ts +0 -134
  64. package/dist/ts/schedule/base/type.ts +0 -142
  65. package/dist/ts/schedule/base/util.d.ts +0 -266
  66. package/dist/ts/schedule/base/util.ts +0 -492
  67. package/dist/ts/schedule/event-renderer/agenda-base.d.ts +0 -15
  68. package/dist/ts/schedule/event-renderer/agenda-base.ts +0 -423
  69. package/dist/ts/schedule/event-renderer/event-base.d.ts +0 -101
  70. package/dist/ts/schedule/event-renderer/event-base.ts +0 -1501
  71. package/dist/ts/schedule/event-renderer/inline-edit.d.ts +0 -23
  72. package/dist/ts/schedule/event-renderer/inline-edit.ts +0 -287
  73. package/dist/ts/schedule/event-renderer/month.d.ts +0 -60
  74. package/dist/ts/schedule/event-renderer/month.ts +0 -760
  75. package/dist/ts/schedule/event-renderer/timeline-view.d.ts +0 -51
  76. package/dist/ts/schedule/event-renderer/timeline-view.ts +0 -606
  77. package/dist/ts/schedule/event-renderer/vertical-view.d.ts +0 -57
  78. package/dist/ts/schedule/event-renderer/vertical-view.ts +0 -898
  79. package/dist/ts/schedule/event-renderer/year.d.ts +0 -27
  80. package/dist/ts/schedule/event-renderer/year.ts +0 -623
  81. package/dist/ts/schedule/exports/calendar-export.d.ts +0 -16
  82. package/dist/ts/schedule/exports/calendar-export.ts +0 -160
  83. package/dist/ts/schedule/exports/calendar-import.d.ts +0 -18
  84. package/dist/ts/schedule/exports/calendar-import.ts +0 -277
  85. package/dist/ts/schedule/exports/excel-export.d.ts +0 -14
  86. package/dist/ts/schedule/exports/excel-export.ts +0 -89
  87. package/dist/ts/schedule/exports/index.d.ts +0 -7
  88. package/dist/ts/schedule/exports/index.ts +0 -7
  89. package/dist/ts/schedule/exports/print.d.ts +0 -20
  90. package/dist/ts/schedule/exports/print.ts +0 -233
  91. package/dist/ts/schedule/index.d.ts +0 -26
  92. package/dist/ts/schedule/index.ts +0 -26
  93. package/dist/ts/schedule/models/event-settings-model.d.ts +0 -165
  94. package/dist/ts/schedule/models/event-settings.d.ts +0 -149
  95. package/dist/ts/schedule/models/event-settings.ts +0 -187
  96. package/dist/ts/schedule/models/field-options-model.d.ts +0 -37
  97. package/dist/ts/schedule/models/field-options.d.ts +0 -31
  98. package/dist/ts/schedule/models/field-options.ts +0 -41
  99. package/dist/ts/schedule/models/fields-model.d.ts +0 -129
  100. package/dist/ts/schedule/models/fields.d.ts +0 -117
  101. package/dist/ts/schedule/models/fields.ts +0 -149
  102. package/dist/ts/schedule/models/group-model.d.ts +0 -69
  103. package/dist/ts/schedule/models/group.d.ts +0 -60
  104. package/dist/ts/schedule/models/group.ts +0 -75
  105. package/dist/ts/schedule/models/header-rows-model.d.ts +0 -33
  106. package/dist/ts/schedule/models/header-rows.d.ts +0 -30
  107. package/dist/ts/schedule/models/header-rows.ts +0 -35
  108. package/dist/ts/schedule/models/models.d.ts +0 -14
  109. package/dist/ts/schedule/models/models.ts +0 -15
  110. package/dist/ts/schedule/models/quick-info-templates-model.d.ts +0 -52
  111. package/dist/ts/schedule/models/quick-info-templates.d.ts +0 -47
  112. package/dist/ts/schedule/models/quick-info-templates.ts +0 -56
  113. package/dist/ts/schedule/models/resources-model.d.ts +0 -122
  114. package/dist/ts/schedule/models/resources.d.ts +0 -106
  115. package/dist/ts/schedule/models/resources.ts +0 -138
  116. package/dist/ts/schedule/models/time-scale-model.d.ts +0 -57
  117. package/dist/ts/schedule/models/time-scale.d.ts +0 -50
  118. package/dist/ts/schedule/models/time-scale.ts +0 -61
  119. package/dist/ts/schedule/models/toolbar-model.d.ts +0 -196
  120. package/dist/ts/schedule/models/toolbar.d.ts +0 -176
  121. package/dist/ts/schedule/models/toolbar.ts +0 -196
  122. package/dist/ts/schedule/models/views-model.d.ts +0 -370
  123. package/dist/ts/schedule/models/views.d.ts +0 -335
  124. package/dist/ts/schedule/models/views.ts +0 -408
  125. package/dist/ts/schedule/models/work-hours-model.d.ts +0 -29
  126. package/dist/ts/schedule/models/work-hours.d.ts +0 -24
  127. package/dist/ts/schedule/models/work-hours.ts +0 -31
  128. package/dist/ts/schedule/popups/event-tooltip.d.ts +0 -16
  129. package/dist/ts/schedule/popups/event-tooltip.ts +0 -203
  130. package/dist/ts/schedule/popups/event-window.d.ts +0 -118
  131. package/dist/ts/schedule/popups/event-window.ts +0 -2055
  132. package/dist/ts/schedule/popups/form-validator.d.ts +0 -16
  133. package/dist/ts/schedule/popups/form-validator.ts +0 -110
  134. package/dist/ts/schedule/popups/quick-popups.d.ts +0 -78
  135. package/dist/ts/schedule/popups/quick-popups.ts +0 -1470
  136. package/dist/ts/schedule/renderer/agenda.d.ts +0 -45
  137. package/dist/ts/schedule/renderer/agenda.ts +0 -497
  138. package/dist/ts/schedule/renderer/day.d.ts +0 -20
  139. package/dist/ts/schedule/renderer/day.ts +0 -28
  140. package/dist/ts/schedule/renderer/header-renderer.d.ts +0 -48
  141. package/dist/ts/schedule/renderer/header-renderer.ts +0 -736
  142. package/dist/ts/schedule/renderer/month-agenda.d.ts +0 -29
  143. package/dist/ts/schedule/renderer/month-agenda.ts +0 -184
  144. package/dist/ts/schedule/renderer/month.d.ts +0 -61
  145. package/dist/ts/schedule/renderer/month.ts +0 -766
  146. package/dist/ts/schedule/renderer/renderer.d.ts +0 -13
  147. package/dist/ts/schedule/renderer/renderer.ts +0 -165
  148. package/dist/ts/schedule/renderer/timeline-header-row.d.ts +0 -15
  149. package/dist/ts/schedule/renderer/timeline-header-row.ts +0 -132
  150. package/dist/ts/schedule/renderer/timeline-month.d.ts +0 -29
  151. package/dist/ts/schedule/renderer/timeline-month.ts +0 -184
  152. package/dist/ts/schedule/renderer/timeline-view.d.ts +0 -31
  153. package/dist/ts/schedule/renderer/timeline-view.ts +0 -308
  154. package/dist/ts/schedule/renderer/timeline-year.d.ts +0 -22
  155. package/dist/ts/schedule/renderer/timeline-year.ts +0 -450
  156. package/dist/ts/schedule/renderer/vertical-view.d.ts +0 -63
  157. package/dist/ts/schedule/renderer/vertical-view.ts +0 -911
  158. package/dist/ts/schedule/renderer/view-base.d.ts +0 -83
  159. package/dist/ts/schedule/renderer/view-base.ts +0 -709
  160. package/dist/ts/schedule/renderer/week.d.ts +0 -22
  161. package/dist/ts/schedule/renderer/week.ts +0 -35
  162. package/dist/ts/schedule/renderer/work-week.d.ts +0 -22
  163. package/dist/ts/schedule/renderer/work-week.ts +0 -36
  164. package/dist/ts/schedule/renderer/year.d.ts +0 -46
  165. package/dist/ts/schedule/renderer/year.ts +0 -470
  166. package/dist/ts/schedule/timezone/timezone.d.ts +0 -16
  167. package/dist/ts/schedule/timezone/timezone.ts +0 -313
@@ -1,898 +0,0 @@
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
- }