@progress/kendo-angular-scheduler 21.4.1-develop.1 → 22.0.0-develop.1

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 (197) hide show
  1. package/editing/recurrence/localization/messages.d.ts +1 -1
  2. package/editing/resource-editor-base.d.ts +1 -1
  3. package/editing-directives/editing-directive-base.d.ts +1 -1
  4. package/fesm2022/progress-kendo-angular-scheduler.mjs +313 -313
  5. package/localization/messages.d.ts +1 -1
  6. package/package.json +20 -28
  7. package/schematics/ngAdd/index.js +3 -3
  8. package/views/common/base-view.d.ts +1 -1
  9. package/views/common/configuration-view-base.d.ts +1 -1
  10. package/views/day-time/day-time-view-base.d.ts +1 -1
  11. package/views/day-time/day-time-view.component.d.ts +1 -1
  12. package/views/multi-day/multi-day-view-base.d.ts +1 -1
  13. package/views/timeline/timeline-base.d.ts +1 -1
  14. package/views/view-items/base-slot.directive.d.ts +1 -1
  15. package/views/view-items/base-view-item.d.ts +1 -1
  16. package/esm2022/common/constants.mjs +0 -8
  17. package/esm2022/common/default-model-fields.mjs +0 -20
  18. package/esm2022/common/dom-queries.mjs +0 -107
  19. package/esm2022/common/modifiers.mjs +0 -31
  20. package/esm2022/common/util.mjs +0 -227
  21. package/esm2022/data-binding.directive.mjs +0 -162
  22. package/esm2022/directives.mjs +0 -136
  23. package/esm2022/editing/date-time-picker.component.mjs +0 -190
  24. package/esm2022/editing/dialogs.service.mjs +0 -96
  25. package/esm2022/editing/edit-dialog-template.directive.mjs +0 -53
  26. package/esm2022/editing/edit-dialog.component.mjs +0 -679
  27. package/esm2022/editing/edit.service.mjs +0 -107
  28. package/esm2022/editing/local-data-changes.service.mjs +0 -18
  29. package/esm2022/editing/recurrence/end-rule-radio-button.directive.mjs +0 -77
  30. package/esm2022/editing/recurrence/localization/custom-messages.component.mjs +0 -44
  31. package/esm2022/editing/recurrence/localization/localized-messages.directive.mjs +0 -39
  32. package/esm2022/editing/recurrence/localization/messages.mjs +0 -239
  33. package/esm2022/editing/recurrence/localization/recurrence-localization.service.mjs +0 -47
  34. package/esm2022/editing/recurrence/recurrence-editor.component.mjs +0 -497
  35. package/esm2022/editing/recurrence/recurrence-end-rule-editor.component.mjs +0 -334
  36. package/esm2022/editing/recurrence/recurrence-frequency-editor.component.mjs +0 -105
  37. package/esm2022/editing/recurrence/recurrence-interval-editor.component.mjs +0 -169
  38. package/esm2022/editing/recurrence/recurrence-monthly-yearly-editor.component.mjs +0 -468
  39. package/esm2022/editing/recurrence/recurrence-weekday-rule-editor.component.mjs +0 -138
  40. package/esm2022/editing/recurrence/recurrence.service.mjs +0 -254
  41. package/esm2022/editing/recurrence/repeat-on-radio-button.directive.mjs +0 -81
  42. package/esm2022/editing/resource-editor-base.mjs +0 -59
  43. package/esm2022/editing/resource-multiple-editor.component.mjs +0 -101
  44. package/esm2022/editing/resource-single-editor.component.mjs +0 -82
  45. package/esm2022/editing/timezone-editor.component.mjs +0 -193
  46. package/esm2022/editing-directives/base-edit.service.mjs +0 -320
  47. package/esm2022/editing-directives/edit-service.interface.mjs +0 -5
  48. package/esm2022/editing-directives/editing-directive-base.mjs +0 -242
  49. package/esm2022/editing-directives/local-edit.service.mjs +0 -122
  50. package/esm2022/editing-directives/reactive-editing.directive.mjs +0 -132
  51. package/esm2022/editing-directives/utils.mjs +0 -107
  52. package/esm2022/events/add-event.mjs +0 -26
  53. package/esm2022/events/cancel-event.mjs +0 -14
  54. package/esm2022/events/create-event.mjs +0 -40
  55. package/esm2022/events/date-change-event.mjs +0 -29
  56. package/esm2022/events/drag-end-event.mjs +0 -46
  57. package/esm2022/events/drag-event.mjs +0 -54
  58. package/esm2022/events/drag-start-event.mjs +0 -30
  59. package/esm2022/events/edit-event-base.mjs +0 -32
  60. package/esm2022/events/edit-event.mjs +0 -30
  61. package/esm2022/events/event-click-event.mjs +0 -32
  62. package/esm2022/events/event-keydown-event.mjs +0 -28
  63. package/esm2022/events/more-events-click.mjs +0 -24
  64. package/esm2022/events/navigate-event.mjs +0 -26
  65. package/esm2022/events/preventable-event.mjs +0 -28
  66. package/esm2022/events/remove-event.mjs +0 -30
  67. package/esm2022/events/resize-end-event.mjs +0 -38
  68. package/esm2022/events/resize-event.mjs +0 -46
  69. package/esm2022/events/resize-start-event.mjs +0 -30
  70. package/esm2022/events/save-event.mjs +0 -18
  71. package/esm2022/events/slot-click-event.mjs +0 -44
  72. package/esm2022/events/slot-drag-end-event.mjs +0 -10
  73. package/esm2022/events/slot-drag-event.mjs +0 -40
  74. package/esm2022/events/slot-drag-start-event.mjs +0 -44
  75. package/esm2022/events/view-event-map.mjs +0 -35
  76. package/esm2022/events.mjs +0 -27
  77. package/esm2022/index.mjs +0 -83
  78. package/esm2022/loading.component.mjs +0 -52
  79. package/esm2022/localization/custom-messages.component.mjs +0 -56
  80. package/esm2022/localization/localized-messages.directive.mjs +0 -39
  81. package/esm2022/localization/messages.mjs +0 -614
  82. package/esm2022/localization/scheduler-localization.service.mjs +0 -31
  83. package/esm2022/navigation/focus-position.interface.mjs +0 -5
  84. package/esm2022/navigation/focus.service.mjs +0 -202
  85. package/esm2022/navigation/focusable-element.interface.mjs +0 -5
  86. package/esm2022/navigation/focusable.directive.mjs +0 -98
  87. package/esm2022/navigation/shortcuts.directive.mjs +0 -239
  88. package/esm2022/navigation.mjs +0 -6
  89. package/esm2022/package-metadata.mjs +0 -16
  90. package/esm2022/pdf/pdf-command.directive.mjs +0 -96
  91. package/esm2022/pdf/pdf-export-event.mjs +0 -10
  92. package/esm2022/pdf/pdf.component.mjs +0 -241
  93. package/esm2022/pdf/pdf.module.mjs +0 -42
  94. package/esm2022/pdf/pdf.service.mjs +0 -36
  95. package/esm2022/progress-kendo-angular-scheduler.mjs +0 -8
  96. package/esm2022/scheduler.component.mjs +0 -1981
  97. package/esm2022/scheduler.module.mjs +0 -138
  98. package/esm2022/toolbar/navigation.component.mjs +0 -391
  99. package/esm2022/toolbar/toolbar-context.mjs +0 -5
  100. package/esm2022/toolbar/toolbar-template.directive.mjs +0 -50
  101. package/esm2022/toolbar/toolbar.component.mjs +0 -168
  102. package/esm2022/toolbar/toolbar.service.mjs +0 -46
  103. package/esm2022/toolbar/view-selector.component.mjs +0 -181
  104. package/esm2022/types/actions.mjs +0 -5
  105. package/esm2022/types/create-form-group-args.interface.mjs +0 -5
  106. package/esm2022/types/crud-operation.enum.mjs +0 -18
  107. package/esm2022/types/current-time-settings.interface.mjs +0 -5
  108. package/esm2022/types/date-range.interface.mjs +0 -5
  109. package/esm2022/types/datepicker-options.interface.mjs +0 -5
  110. package/esm2022/types/edit-event-args.interface.mjs +0 -5
  111. package/esm2022/types/edit-mode.enum.mjs +0 -23
  112. package/esm2022/types/editable-settings.interface.mjs +0 -5
  113. package/esm2022/types/event-style-args.interface.mjs +0 -5
  114. package/esm2022/types/focusable-container.mjs +0 -5
  115. package/esm2022/types/group.interface.mjs +0 -5
  116. package/esm2022/types/numeric-options.interface.mjs +0 -5
  117. package/esm2022/types/ongoing-events-settings.interface.mjs +0 -5
  118. package/esm2022/types/resource.interface.mjs +0 -5
  119. package/esm2022/types/scheduler-event.mjs +0 -5
  120. package/esm2022/types/scheduler-model-fields.interface.mjs +0 -5
  121. package/esm2022/types/scheduler-slot.interface.mjs +0 -5
  122. package/esm2022/types/scheduler-view.mjs +0 -9
  123. package/esm2022/types/slot-class-args.interface.mjs +0 -5
  124. package/esm2022/types/slot-selection.mjs +0 -35
  125. package/esm2022/types/view-item.interface.mjs +0 -5
  126. package/esm2022/types.mjs +0 -12
  127. package/esm2022/views/agenda/agenda-header-item.component.mjs +0 -85
  128. package/esm2022/views/agenda/agenda-header.component.mjs +0 -75
  129. package/esm2022/views/agenda/agenda-task-item.component.mjs +0 -137
  130. package/esm2022/views/agenda/agenda-view-internal.component.mjs +0 -424
  131. package/esm2022/views/agenda/agenda-view-list.component.mjs +0 -256
  132. package/esm2022/views/agenda/agenda-view.component.mjs +0 -130
  133. package/esm2022/views/agenda/tasks.collection.mjs +0 -96
  134. package/esm2022/views/agenda/utils.mjs +0 -176
  135. package/esm2022/views/common/base-view.mjs +0 -1099
  136. package/esm2022/views/common/configuration-view-base.mjs +0 -164
  137. package/esm2022/views/common/dom-events.service.mjs +0 -22
  138. package/esm2022/views/common/hint-container.component.mjs +0 -41
  139. package/esm2022/views/common/repeat.pipe.mjs +0 -36
  140. package/esm2022/views/common/resize-hint.component.mjs +0 -97
  141. package/esm2022/views/common/resource-iterator.pipe.mjs +0 -49
  142. package/esm2022/views/common/scheduler-task.mjs +0 -5
  143. package/esm2022/views/common/slot-selectable.directive.mjs +0 -137
  144. package/esm2022/views/common/view-footer.component.mjs +0 -103
  145. package/esm2022/views/common/work-hours-footer.directive.mjs +0 -45
  146. package/esm2022/views/constants.mjs +0 -31
  147. package/esm2022/views/day-time/day-time-slot.service.mjs +0 -633
  148. package/esm2022/views/day-time/day-time-view-base.mjs +0 -244
  149. package/esm2022/views/day-time/day-time-view-item.component.mjs +0 -216
  150. package/esm2022/views/day-time/day-time-view.component.mjs +0 -437
  151. package/esm2022/views/day-time/event-slot.directive.mjs +0 -138
  152. package/esm2022/views/day-time/utils.mjs +0 -32
  153. package/esm2022/views/month/month-slot.component.mjs +0 -166
  154. package/esm2022/views/month/month-slot.service.mjs +0 -404
  155. package/esm2022/views/month/month-view-item.component.mjs +0 -161
  156. package/esm2022/views/month/month-view-renderer.component.mjs +0 -683
  157. package/esm2022/views/month/month-view.component.mjs +0 -203
  158. package/esm2022/views/month/multi-week-view.component.mjs +0 -202
  159. package/esm2022/views/month/utils.mjs +0 -107
  160. package/esm2022/views/multi-day/day-view.component.mjs +0 -186
  161. package/esm2022/views/multi-day/multi-day-view-base.mjs +0 -55
  162. package/esm2022/views/multi-day/multi-day-view-renderer.component.mjs +0 -1002
  163. package/esm2022/views/multi-day/multi-day-view.component.mjs +0 -197
  164. package/esm2022/views/multi-day/utils.mjs +0 -63
  165. package/esm2022/views/multi-day/week-view.component.mjs +0 -189
  166. package/esm2022/views/multi-day/work-week-view.component.mjs +0 -172
  167. package/esm2022/views/scheduler-view.directive.mjs +0 -65
  168. package/esm2022/views/templates/agenda-date-template.directive.mjs +0 -41
  169. package/esm2022/views/templates/agenda-time-template.directive.mjs +0 -46
  170. package/esm2022/views/templates/all-day-event-template.directive.mjs +0 -42
  171. package/esm2022/views/templates/all-day-slot-template.directive.mjs +0 -42
  172. package/esm2022/views/templates/date-header-template.directive.mjs +0 -42
  173. package/esm2022/views/templates/event-template.directive.mjs +0 -42
  174. package/esm2022/views/templates/group-header-template.directive.mjs +0 -42
  175. package/esm2022/views/templates/major-time-header-template.directive.mjs +0 -41
  176. package/esm2022/views/templates/minor-time-header-template.directive.mjs +0 -41
  177. package/esm2022/views/templates/month-day-slot-template.directive.mjs +0 -42
  178. package/esm2022/views/templates/multi-week-day-slot-template.directive.mjs +0 -42
  179. package/esm2022/views/templates/time-slot-template.directive.mjs +0 -43
  180. package/esm2022/views/templates.mjs +0 -16
  181. package/esm2022/views/timeline/timeline-base.mjs +0 -39
  182. package/esm2022/views/timeline/timeline-month-view.component.mjs +0 -211
  183. package/esm2022/views/timeline/timeline-multi-day-view.component.mjs +0 -649
  184. package/esm2022/views/timeline/timeline-view.component.mjs +0 -189
  185. package/esm2022/views/timeline/timeline-week-view.component.mjs +0 -181
  186. package/esm2022/views/timeline/utils.mjs +0 -60
  187. package/esm2022/views/utils.mjs +0 -373
  188. package/esm2022/views/view-context.service.mjs +0 -111
  189. package/esm2022/views/view-items/base-slot.directive.mjs +0 -104
  190. package/esm2022/views/view-items/base-slot.service.mjs +0 -82
  191. package/esm2022/views/view-items/base-view-item.mjs +0 -194
  192. package/esm2022/views/view-items/item-map.mjs +0 -38
  193. package/esm2022/views/view-items/types.mjs +0 -5
  194. package/esm2022/views/view-state.service.mjs +0 -144
  195. package/esm2022/views/year/utils.mjs +0 -60
  196. package/esm2022/views/year/year-view-internal.component.mjs +0 -471
  197. package/esm2022/views/year/year-view.component.mjs +0 -136
@@ -1,633 +0,0 @@
1
- /**-----------------------------------------------------------------------------------------
2
- * Copyright © 2026 Progress Software Corporation. All rights reserved.
3
- * Licensed under commercial license. See LICENSE.md in the project root for more information
4
- *-------------------------------------------------------------------------------------------*/
5
- import { orderBy } from '@progress/kendo-data-query';
6
- import { intersects, findRowIndex } from '../utils';
7
- import { ItemMap } from '../view-items/item-map';
8
- import { BaseSlotService } from '../view-items/base-slot.service';
9
- import { rectContains, rectContainsX, dateInRange, dateWithTime } from '../utils';
10
- import { isNumber } from '../../common/util';
11
- const EVENTS_OFFSET = 10;
12
- const MIN_EVENT_HEIGHT = 25;
13
- const minHeightOverlaps = (top1, top2) => top1 <= top2 && top2 <= top1 + MIN_EVENT_HEIGHT;
14
- const timeOffset = (slot, date, vertical = true) => {
15
- if (slot.start.getTime() <= date.getTime()) {
16
- return (vertical ? slot.height : slot.width) * ((date.getTime() - slot.start.getTime()) / (slot.end.getTime() - slot.start.getTime()));
17
- }
18
- return 0;
19
- };
20
- const columnIndexComparer = (a, b) => {
21
- const indexA = isNumber(a.columnIndex) ? a.columnIndex : Number.MAX_VALUE;
22
- const indexB = isNumber(b.columnIndex) ? b.columnIndex : Number.MAX_VALUE;
23
- // a un b def = 0
24
- // b un a def = 0
25
- if (indexA === indexB) {
26
- return a.item.startTime.getTime() - b.item.startTime.getTime();
27
- }
28
- return indexA - indexB;
29
- };
30
- function initTimeColumns(slotKeys, slotItems) {
31
- // Break slots into groups with overlapping events.
32
- let columns = 0;
33
- let groupSlots = [];
34
- slotKeys.forEach(key => {
35
- const { slot, events } = slotItems[key];
36
- const count = events.length;
37
- let groupEnd = true;
38
- events.sort(columnIndexComparer);
39
- columns = Math.max(count, columns);
40
- groupSlots.push(slot);
41
- for (let eventIdx = 0; eventIdx < count; eventIdx++) {
42
- const event = events[eventIdx];
43
- groupEnd = groupEnd && event.item.endTime.getTime() <= slot.end.getTime();
44
- if (isNumber(event.columnIndex)) {
45
- continue;
46
- }
47
- event.rect = {
48
- top: slot.rect.top + timeOffset(slot, event.item.startTime)
49
- };
50
- event.columnIndex = eventIdx;
51
- event.lastColumn = true;
52
- for (let idx = 0, previousIdx = -1; idx < eventIdx; idx++) {
53
- const current = events[idx];
54
- if (current.columnIndex > previousIdx + 1) {
55
- event.columnIndex = previousIdx + 1;
56
- event.lastColumn = false;
57
- events.splice(eventIdx, 1);
58
- events.splice(event.columnIndex, 0, event);
59
- break;
60
- }
61
- //events that don't intersect their start or end times but overlap in rendered height due to the minimum event height
62
- const anyOverlappingEvents = events.filter(e => e !== current && e.rect).some(event => {
63
- const areIntersecting = intersects(event.item.startTime, event.item.endTime, current.item.startTime, current.item.endTime);
64
- const areOverlapping = minHeightOverlaps(current.rect.top, event.rect.top);
65
- return !areIntersecting && areOverlapping;
66
- });
67
- const intersectingEvents = intersects(event.item.startTime, event.item.endTime, current.item.startTime, current.item.endTime);
68
- const overlappingEvents = minHeightOverlaps(current.rect.top, event.rect.top);
69
- if (!(anyOverlappingEvents || intersectingEvents || overlappingEvents)) {
70
- const currentSlotDay = new Date(slot.start).toDateString();
71
- const hasPreviousSlotsWithMoreOrSameColumns = slotKeys.some(previousKey => {
72
- const previousSlot = slotItems[previousKey].slot;
73
- const previousSlotDay = new Date(previousSlot.start).toDateString();
74
- return previousSlotDay === currentSlotDay &&
75
- previousSlot.start < slot.start &&
76
- previousSlot.columns >= (columns - 1);
77
- });
78
- if (!hasPreviousSlotsWithMoreOrSameColumns) {
79
- columns--;
80
- }
81
- event.columnIndex = idx;
82
- event.lastColumn = !events.some((e) => {
83
- const hasColumnIndex = e.columnIndex;
84
- const isBeforeCurrentIndex = idx < e.columnIndex;
85
- const areIntersecting = intersects(event.item.startTime, event.item.endTime, e.item.startTime, e.item.endTime);
86
- return hasColumnIndex && isBeforeCurrentIndex && areIntersecting;
87
- });
88
- events.splice(eventIdx, 1);
89
- events.splice(idx, 0, event);
90
- break;
91
- }
92
- previousIdx = current.columnIndex;
93
- current.lastColumn = false;
94
- }
95
- }
96
- if (groupEnd) {
97
- groupSlots.forEach(item => item.columns = columns);
98
- groupSlots = [];
99
- columns = 0;
100
- }
101
- });
102
- // The maximum number of overlapping events in the group is used to create the same number of columns.
103
- groupSlots.forEach(slot => slot.columns = columns);
104
- }
105
- function findTimeRowIndex(events, event) {
106
- if (event.rowIndex !== undefined) {
107
- return event.rowIndex;
108
- }
109
- for (let idx = 0; idx < events.length; idx++) {
110
- const current = events[idx];
111
- if (!current || !intersects(event.item.startTime, event.item.endTime, current.item.startTime, current.item.endTime)) {
112
- return idx;
113
- }
114
- }
115
- return events.length;
116
- }
117
- function initHorizontalSlots(slots, items, rowHeight, eventHeight, getRowIndex) {
118
- const padding = slots[0].padding;
119
- if (!items.length) {
120
- return {
121
- height: rowHeight - padding
122
- };
123
- }
124
- items.forEach(item => {
125
- item.rowIndex = undefined;
126
- item.rect = {
127
- height: eventHeight,
128
- width: 0
129
- };
130
- });
131
- const sorted = orderBy(items, [{ field: "item.startTime", dir: "asc" }, { field: "item.endTime", dir: "desc" }]);
132
- const slotItems = {};
133
- sorted.forEach(event => slots
134
- .filter(slot => intersects(event.item.startTime, event.item.endTime, slot.start, slot.end))
135
- .forEach(slot => {
136
- const value = slotItems[slot.key] = slotItems[slot.key] || { rows: [], slot: slot, events: [] };
137
- event.rowIndex = getRowIndex(value.rows, event);
138
- value.rows[event.rowIndex] = event;
139
- value.events.push(event);
140
- }));
141
- const top = slots[0].top;
142
- let maxOffset = 0;
143
- Object.keys(slotItems).forEach((key) => {
144
- const events = slotItems[key].events;
145
- let slotOffset = 0;
146
- for (let idx = 0; idx < events.length; idx++) {
147
- const event = events[idx];
148
- if (event) {
149
- event.rect.top = top + event.rowIndex * (EVENTS_OFFSET + event.rect.height);
150
- slotOffset = Math.max(slotOffset, (event.rect.top - top) + event.rect.height);
151
- }
152
- }
153
- maxOffset = Math.max(slotOffset, maxOffset);
154
- });
155
- maxOffset += rowHeight - padding;
156
- return {
157
- height: maxOffset,
158
- slotItems
159
- };
160
- }
161
- function setHorizontalOffsets(slotItems, items, measureTime) {
162
- Object.keys(slotItems).forEach((key) => {
163
- const { slot, events } = slotItems[key];
164
- const rect = slot.rect;
165
- for (let idx = 0; idx < events.length; idx++) {
166
- const event = events[idx];
167
- if (event) {
168
- if (!isNumber(event.rect.left)) {
169
- event.rect.left = slot.rect.left +
170
- (measureTime ? timeOffset(slot, event.item.startTime, false) : 0);
171
- }
172
- const slotOffset = measureTime && event.item.endTime.getTime() < slot.end.getTime() ?
173
- timeOffset(slot, event.item.endTime, false) : rect.width;
174
- event.rect.width = slot.rect.left + slotOffset - event.rect.left;
175
- }
176
- }
177
- });
178
- items.forEach(item => {
179
- item.reflow();
180
- });
181
- }
182
- /** @hidden */
183
- export class SlotRange {
184
- index;
185
- get slots() {
186
- return this.slotMap.toArray();
187
- }
188
- get firstSlot() {
189
- return this.slotMap.first;
190
- }
191
- get lastSlot() {
192
- return this.slotMap.last;
193
- }
194
- get items() {
195
- return this.itemMap.toArray();
196
- }
197
- get rect() {
198
- const first = this.firstSlot.rect;
199
- const last = this.lastSlot.rect;
200
- return {
201
- left: first.left,
202
- top: first.top,
203
- width: last.left - first.left + last.width,
204
- height: last.top - first.top + last.height
205
- };
206
- }
207
- slotMap = new ItemMap();
208
- itemMap = new ItemMap();
209
- slotItems;
210
- get start() {
211
- const first = this.slotMap.first;
212
- if (!first) {
213
- return null;
214
- }
215
- return first.start;
216
- }
217
- get end() {
218
- const last = this.slotMap.last;
219
- if (!last) {
220
- return null;
221
- }
222
- return last.end;
223
- }
224
- get hasSlots() {
225
- return this.slotMap.count > 0;
226
- }
227
- get hasItems() {
228
- return this.itemMap.count > 0;
229
- }
230
- constructor(index) {
231
- this.index = index;
232
- }
233
- registerItem(component) {
234
- this.itemMap.addItem(component.item.index, component);
235
- }
236
- unregisterItem(component, id) {
237
- this.itemMap.removeItem(id.index, component);
238
- }
239
- registerSlot(slot) {
240
- this.slotMap.addItem(slot.id.index, slot);
241
- }
242
- unregisterSlot(slot) {
243
- this.slotMap.removeItem(slot.id.index, slot);
244
- }
245
- layout(options) {
246
- const items = this.items;
247
- if (!items.length) {
248
- return;
249
- }
250
- const fill = Math.max(Math.min(options.fill || 0.9, 1), 0.1);
251
- const sorted = orderBy(items, [{ field: "item.startTime", dir: "asc" }, { field: "item.endTime", dir: "desc" }]);
252
- items.forEach((item, _index) => {
253
- item.rect = null;
254
- item.columnIndex = undefined;
255
- });
256
- const slotItems = {};
257
- const slots = this.slots;
258
- // Map each populated slot to the events in it
259
- sorted.forEach(event => slots
260
- .filter(slot => intersects(event.item.startTime, event.item.endTime, slot.start, slot.end))
261
- .forEach(slot => {
262
- const value = slotItems[slot.key] = slotItems[slot.key] || { events: [] };
263
- value.slot = slot;
264
- value.events.push(event);
265
- }));
266
- const slotKeys = Object.keys(slotItems);
267
- initTimeColumns(slotKeys, slotItems);
268
- slotKeys.forEach((key) => {
269
- const { slot, events } = slotItems[key];
270
- const spacing = 2;
271
- const startOffset = 2;
272
- const slotRect = slot.rect;
273
- const slotLeft = slotRect.left;
274
- const columns = slot.columns;
275
- const slotWidth = slotRect.width * fill - (columns - 1) * spacing - startOffset;
276
- const origin = slotLeft + startOffset;
277
- const eventWidth = slotWidth / columns;
278
- const slotEnd = origin + slotWidth + (columns - 1) * spacing;
279
- events.forEach(event => {
280
- if (!isNumber(event.rect.left)) {
281
- event.rect.left = origin + event.columnIndex * (eventWidth + spacing);
282
- event.rect.width = event.lastColumn ? slotEnd - event.rect.left : eventWidth;
283
- event.origin = {
284
- left: slotLeft,
285
- right: slotLeft + slotRect.width
286
- };
287
- }
288
- // Expand the event to the last group slot
289
- const slotOffset = slot.end.getTime() <= event.item.endTime.getTime() ? slotRect.height : timeOffset(slot, event.item.endTime);
290
- event.rect.height = slotRect.top + slotOffset - event.rect.top;
291
- });
292
- });
293
- sorted.forEach(event => event.reflow());
294
- }
295
- initDaySlots(rowHeight, eventHeight) {
296
- const slots = this.slots;
297
- if (!slots.length) {
298
- return;
299
- }
300
- const { height, slotItems } = initHorizontalSlots(slots, this.items, rowHeight, eventHeight, findRowIndex);
301
- this.setSlotsHeight(height);
302
- this.slotItems = slotItems;
303
- }
304
- setDayOffsets() {
305
- if (!this.itemMap.count || !this.slotItems) {
306
- return;
307
- }
308
- setHorizontalOffsets(this.slotItems, this.items);
309
- this.slotItems = null;
310
- }
311
- setSlotsHeight(height) {
312
- this.firstSlot.height = height;
313
- }
314
- }
315
- /**
316
- * @hidden
317
- */
318
- export class DayTimeResourceGroup {
319
- index;
320
- dayRanges = [];
321
- timeRanges = [];
322
- slotItems;
323
- constructor(index) {
324
- this.index = index;
325
- }
326
- registerSlot(slot) {
327
- const range = this.slotRange(slot);
328
- range.registerSlot(slot);
329
- }
330
- unregisterSlot(slot) {
331
- const range = this.slotRange(slot);
332
- range.unregisterSlot(slot);
333
- if (!range.hasSlots) {
334
- const ranges = this.slotRanges(slot);
335
- ranges[slot.id.rangeIndex] = undefined;
336
- }
337
- }
338
- registerItem(component) {
339
- const range = this.itemRange(component);
340
- if (range) {
341
- range.registerItem(component);
342
- component.rangeIndex = range.index;
343
- if (component.resourceIndex >= 0) {
344
- component.toggle(true);
345
- }
346
- }
347
- else {
348
- component.rangeIndex = undefined;
349
- component.toggle(false);
350
- }
351
- }
352
- unregisterItem(component, id) {
353
- if (component.rangeIndex !== undefined) {
354
- const ranges = component.item.isAllDay ? this.dayRanges : this.timeRanges;
355
- if (ranges[id.rangeIndex]) {
356
- ranges[id.rangeIndex].unregisterItem(component, id);
357
- }
358
- component.rangeIndex = undefined;
359
- }
360
- }
361
- forEachDateRange(callback) {
362
- for (let i = 0; i < this.dayRanges.length; i++) {
363
- callback(this.dayRanges[i]);
364
- }
365
- }
366
- forEachTimeRange(callback) {
367
- for (let i = 0; i < this.timeRanges.length; i++) {
368
- callback(this.timeRanges[i]);
369
- }
370
- }
371
- slotRange(slot) {
372
- const ranges = this.slotRanges(slot);
373
- const rangeIndex = slot.id.rangeIndex;
374
- if (!ranges[rangeIndex]) {
375
- ranges[rangeIndex] = new SlotRange(rangeIndex);
376
- }
377
- return ranges[rangeIndex];
378
- }
379
- slotRanges(slot) {
380
- return slot.isDaySlot ? this.dayRanges : this.timeRanges;
381
- }
382
- initTimeSlots(rowHeight, eventHeight, resourceRowHeight) {
383
- const slots = this.slots;
384
- if (!slots.length) {
385
- return;
386
- }
387
- const { height, slotItems } = initHorizontalSlots(slots, this.items, rowHeight, eventHeight, findTimeRowIndex);
388
- this.setSlotsHeight(Math.max(height, resourceRowHeight));
389
- this.slotItems = slotItems;
390
- }
391
- setTimelineOffsets() {
392
- const items = this.items;
393
- if (!this.slotItems || !items.length) {
394
- return;
395
- }
396
- setHorizontalOffsets(this.slotItems, items, true);
397
- this.slotItems = null;
398
- }
399
- setSlotsHeight(height) {
400
- //setting the first slot height should be sufficient
401
- this.timeRanges[0].setSlotsHeight(height);
402
- }
403
- get items() {
404
- return this.timeRanges.reduce((acc, range) => acc.concat(range.items), []);
405
- }
406
- get slots() {
407
- return this.timeRanges.reduce((acc, range) => acc.concat(range.slots), []);
408
- }
409
- get hasSlots() {
410
- return Boolean(this.dayRanges.find(range => range?.hasSlots) || this.timeRanges.find(range => range?.hasSlots));
411
- }
412
- cleanRanges() {
413
- this.dayRanges = this.dayRanges.filter(r => Boolean(r));
414
- this.timeRanges = this.timeRanges.filter(r => Boolean(r));
415
- }
416
- itemRange(component) {
417
- const task = component.item;
418
- const ranges = task.isAllDay ? this.dayRanges : this.timeRanges;
419
- if (isNumber(task.rangeIndex)) {
420
- return ranges[task.rangeIndex];
421
- }
422
- return ranges.find(r => intersects(task.startTime, task.endTime, r.start, r.end));
423
- }
424
- }
425
- /**
426
- * @hidden
427
- */
428
- export class DayTimeSlotService extends BaseSlotService {
429
- hiddenDays = [];
430
- layoutDays(eventHeight = 25) {
431
- this.groups.forEach((group) => group.forEachDateRange(range => range?.slots.forEach(slot => {
432
- slot.element.nativeElement.style.height = '';
433
- })));
434
- const rowHeight = this.groups[0].dayRanges[0]?.slots[0].height;
435
- this.groups.forEach((group) => {
436
- group.forEachDateRange(range => range.initDaySlots(rowHeight, eventHeight));
437
- });
438
- this.groups.forEach((group) => {
439
- group.forEachDateRange(range => range.setDayOffsets());
440
- });
441
- }
442
- layoutTimeline(eventHeight, resourceRows) {
443
- this.groups.forEach((group) => group.forEachTimeRange(range => range?.slots.forEach(slot => {
444
- slot.element.nativeElement.style.height = '';
445
- })));
446
- const rowHeight = this.groups[0].timeRanges[0]?.slots[0].height;
447
- this.groups.forEach((group, index) => {
448
- group.initTimeSlots(rowHeight, eventHeight, resourceRows?.[index] ? resourceRows[index].nativeElement.children[0]?.children[0].offsetHeight : 0);
449
- });
450
- this.groups.forEach((group) => group.setTimelineOffsets());
451
- }
452
- layoutTimes(options) {
453
- this.groups.forEach((group) => group.forEachTimeRange(range => range.layout(options)));
454
- }
455
- forEachDateRange(callback) {
456
- this.groups.forEach((group, index) => {
457
- callback(group.dayRanges[0], index);
458
- });
459
- }
460
- syncDateRanges() {
461
- let maxHeight = 0;
462
- this.groups.forEach((group) => {
463
- const slot = group.dayRanges[0]?.firstSlot;
464
- if (slot) {
465
- maxHeight = Math.max(slot.rect.height - slot.padding, maxHeight);
466
- }
467
- });
468
- this.groups.forEach((group) => {
469
- group.dayRanges[0]?.setSlotsHeight(maxHeight);
470
- });
471
- return maxHeight;
472
- }
473
- forEachGroup(callback) {
474
- this.groups.forEach(callback);
475
- }
476
- forEachSlot(callback) {
477
- this.groups.forEach((group) => {
478
- group.dayRanges.forEach(range => {
479
- range?.slots.forEach(slot => callback(slot));
480
- });
481
- group.timeRanges.forEach(range => {
482
- range?.slots.forEach(slot => callback(slot));
483
- });
484
- });
485
- }
486
- createGroup(index) {
487
- return new DayTimeResourceGroup(index);
488
- }
489
- slotByIndex(slotIndex, allDay = false) {
490
- const [resourceIndex, rangeIndex, index] = slotIndex.split(':').map(part => parseInt(part, 10));
491
- return this.groups[resourceIndex][allDay ? 'dayRanges' : 'timeRanges'][rangeIndex]?.slots[index];
492
- }
493
- slotByPosition(x, y, isDaySlot, includeDayRanges) {
494
- if (isDaySlot) {
495
- for (let i = 0; i < this.groups.length; i++) {
496
- const foundRange = this.groups[i].dayRanges.find(r => rectContainsX(r.rect, x, this.calculateScaleX()));
497
- if (foundRange) {
498
- return foundRange.slots.find(slot => rectContainsX(slot.rect, x, this.calculateScaleX()));
499
- }
500
- }
501
- }
502
- else {
503
- for (let i = 0; i < this.groups.length; i++) {
504
- let range;
505
- if (includeDayRanges) {
506
- range = this.groups[i].dayRanges.find(r => rectContains(r.rect, x, y, this.calculateScaleX()));
507
- }
508
- if (!range) {
509
- range = this.groups[i].timeRanges.find(r => rectContains(r.rect, x, y, this.calculateScaleX()));
510
- }
511
- if (range) {
512
- return range.slots.find(slot => rectContains(slot.rect, x, y, this.calculateScaleX()));
513
- }
514
- }
515
- }
516
- }
517
- groupSlotByPosition(currentSlot, x, y) {
518
- const group = this.groups[currentSlot.id.resourceIndex];
519
- let range;
520
- if (currentSlot.isDaySlot) {
521
- range = group.dayRanges.find(r => rectContains(r.rect, x, y, this.calculateScaleX()));
522
- }
523
- else {
524
- range = group.timeRanges.find(r => rectContains(r.rect, x, y, this.calculateScaleX()));
525
- }
526
- if (range) {
527
- return range.slots.find(slot => rectContains(slot.rect, x, y, this.calculateScaleX()));
528
- }
529
- }
530
- dragRanges(currentSlot, offset, timeRanges) {
531
- const start = new Date(currentSlot.start.getTime() - offset.start);
532
- const end = new Date(currentSlot.start.getTime() + offset.end);
533
- const group = this.groups[currentSlot.id.resourceIndex];
534
- let result;
535
- if (timeRanges) {
536
- const slotRanges = [];
537
- group.timeRanges.forEach(range => {
538
- const slots = range?.slots.filter(s => intersects(start, end, s.start, s.end));
539
- if (slots.length) {
540
- slotRanges.push(slots);
541
- }
542
- });
543
- const lastRange = slotRanges[slotRanges.length - 1];
544
- result = [slotRanges[0][0], lastRange[lastRange.length - 1]];
545
- }
546
- else {
547
- result = group.slotRange(currentSlot)?.slots.filter(s => intersects(start, end, s.start, s.end));
548
- }
549
- return {
550
- start,
551
- end,
552
- ranges: [result]
553
- };
554
- }
555
- resizeRanges(currentSlot, task, resizeStart, offset) {
556
- const group = this.groups[currentSlot.id.resourceIndex];
557
- const ranges = task.isAllDay ? group.dayRanges : group.timeRanges;
558
- const result = [];
559
- const startDate = task.start.toUTCDate();
560
- const endDate = task.end.toUTCDate();
561
- let start, end;
562
- if (resizeStart) {
563
- const startTime = currentSlot.start.getTime() + offset.start;
564
- end = startDate.getTime() === endDate.getTime() ? this.findDateSlot(endDate, ranges, true).end : endDate;
565
- if (startTime >= endDate.getTime()) {
566
- if (task.isAllDay) {
567
- start = new Date(Math.min(dateWithTime(endDate, startDate).getTime(), endDate.getTime()));
568
- }
569
- else {
570
- start = this.findDateSlot(end, ranges).start;
571
- }
572
- }
573
- else if (offset.start && task.isAllDay) {
574
- start = new Date(startTime);
575
- }
576
- else {
577
- start = new Date(currentSlot.start.getTime());
578
- }
579
- }
580
- else {
581
- start = startDate;
582
- if (currentSlot.start.getTime() <= start.getTime()) {
583
- if (task.isAllDay) {
584
- end = new Date(Math.max(dateWithTime(startDate, endDate).getTime(), startDate.getTime()));
585
- }
586
- else {
587
- end = this.findDateSlot(start, ranges, true).end;
588
- }
589
- }
590
- else if (offset.end && task.isAllDay) {
591
- end = new Date(currentSlot.start.getTime() + offset.end);
592
- }
593
- else {
594
- end = currentSlot.end;
595
- }
596
- }
597
- ranges.forEach(range => {
598
- const slots = range.slots.filter(s => intersects(start, end, s.start, s.end));
599
- if (slots.length) {
600
- result.push(slots);
601
- }
602
- });
603
- return {
604
- start,
605
- end,
606
- ranges: result
607
- };
608
- }
609
- timePosition(date, resourceIndex, vertical) {
610
- const group = this.groups[resourceIndex];
611
- const range = group.timeRanges.find(r => dateInRange(date, r.start, r.end));
612
- if (!range) {
613
- return;
614
- }
615
- const slot = range.slots.find(s => dateInRange(date, s.start, s.end));
616
- if (slot) {
617
- const position = (vertical ? slot.height : slot.width) *
618
- ((date.getTime() - slot.start.getTime()) / (slot.end.getTime() - slot.start.getTime()));
619
- return vertical ? slot.rect.top + position : slot.rect.left + position;
620
- }
621
- }
622
- findDateSlot(date, ranges, excludeEnd) {
623
- let result;
624
- ranges.forEach(range => {
625
- const slots = excludeEnd ? range.slots.filter(s => intersects(date, date, s.start, s.end)) :
626
- range.slots.filter(s => dateInRange(date, s.start, s.end));
627
- if (slots.length) {
628
- result = slots[0];
629
- }
630
- });
631
- return result;
632
- }
633
- }