@primeui/scheduler-core 0.0.1-alpha.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 (63) hide show
  1. package/LICENSE +23 -0
  2. package/README.md +1 -0
  3. package/dist/calendar/index.d.mts +57 -0
  4. package/dist/calendar/index.mjs +1 -0
  5. package/dist/chunk-2B3YLWHA.mjs +196 -0
  6. package/dist/chunk-2THQAZ26.mjs +1669 -0
  7. package/dist/chunk-5KORIWDT.mjs +41 -0
  8. package/dist/chunk-5N4ZOBJV.mjs +866 -0
  9. package/dist/chunk-6OZAPQZ5.mjs +229 -0
  10. package/dist/chunk-6PK5WSKT.mjs +369 -0
  11. package/dist/chunk-6VYWVIGM.mjs +1170 -0
  12. package/dist/chunk-AAVM7UCG.mjs +100 -0
  13. package/dist/chunk-C7ADJGNV.mjs +157 -0
  14. package/dist/chunk-DYW6WUHE.mjs +277 -0
  15. package/dist/chunk-F5W5HD7S.mjs +285 -0
  16. package/dist/chunk-FIBAZFC4.mjs +871 -0
  17. package/dist/chunk-HPC5B3AR.mjs +558 -0
  18. package/dist/chunk-KQGRXTP5.mjs +650 -0
  19. package/dist/chunk-NMX4BW42.mjs +672 -0
  20. package/dist/chunk-NX46LPLF.mjs +440 -0
  21. package/dist/chunk-NZGJN7HG.mjs +314 -0
  22. package/dist/chunk-QDMZBJDV.mjs +251 -0
  23. package/dist/chunk-QR2SVYAD.mjs +1144 -0
  24. package/dist/chunk-SYJ5O4KH.mjs +136 -0
  25. package/dist/chunk-TNKJPFGI.mjs +569 -0
  26. package/dist/chunk-UMAMDBU4.mjs +1 -0
  27. package/dist/chunk-W2SJW3QQ.mjs +3925 -0
  28. package/dist/chunk-WFUJWDST.mjs +352 -0
  29. package/dist/chunk-XUBQ2IQS.mjs +1 -0
  30. package/dist/chunk-ZUKUKGNK.mjs +613 -0
  31. package/dist/controllers/index.d.mts +384 -0
  32. package/dist/controllers/index.mjs +13 -0
  33. package/dist/date-D_CjQPmM.d.mts +74 -0
  34. package/dist/display-format-CLVvRt4I.d.mts +57 -0
  35. package/dist/event/index.d.mts +267 -0
  36. package/dist/event/index.mjs +8 -0
  37. package/dist/event-surface-_R_LHD95.d.mts +21 -0
  38. package/dist/event.positioning-BdzAVPk7.d.mts +51 -0
  39. package/dist/event.utils-QSNdd-3W.d.mts +35 -0
  40. package/dist/index.d.mts +1128 -0
  41. package/dist/index.mjs +1022 -0
  42. package/dist/interaction/index.d.mts +442 -0
  43. package/dist/interaction/index.mjs +9 -0
  44. package/dist/month/index.d.mts +104 -0
  45. package/dist/month/index.mjs +6 -0
  46. package/dist/overlay-BYM9B6nC.d.mts +64 -0
  47. package/dist/resource/index.d.mts +172 -0
  48. package/dist/resource/index.mjs +1 -0
  49. package/dist/selection-CO_98HdS.d.mts +56 -0
  50. package/dist/time-grid/index.d.mts +92 -0
  51. package/dist/time-grid/index.mjs +13 -0
  52. package/dist/timeline/index.d.mts +165 -0
  53. package/dist/timeline/index.mjs +6 -0
  54. package/dist/touch-BhsMWsjf.d.mts +69 -0
  55. package/dist/utils/index.d.mts +494 -0
  56. package/dist/utils/index.mjs +17 -0
  57. package/dist/views/index.d.mts +51 -0
  58. package/dist/views/index.mjs +8 -0
  59. package/dist/views/timeline/index.d.mts +37 -0
  60. package/dist/views/timeline/index.mjs +4 -0
  61. package/dist/year/index.d.mts +70 -0
  62. package/dist/year/index.mjs +6 -0
  63. package/package.json +58 -0
@@ -0,0 +1,558 @@
1
+ import { parseRRule } from './chunk-FIBAZFC4.mjs';
2
+ import { timeStringToMinutes } from './chunk-WFUJWDST.mjs';
3
+ import { createSchedulerDateFormatter, formatTimeRange } from './chunk-TNKJPFGI.mjs';
4
+
5
+ // src/utils/blocked-intervals.ts
6
+ function parseDate(date) {
7
+ return typeof date === "string" ? new Date(date) : new Date(date);
8
+ }
9
+ function isTimeOnlyFormat(value) {
10
+ return /^\d{1,2}:\d{2}(:\d{2})?$/.test(value);
11
+ }
12
+ function combineDateAndTime(date, timeStr) {
13
+ const result = new Date(date);
14
+ const parts = timeStr.split(":").map(Number);
15
+ const hours = parts[0] ?? 0;
16
+ const minutes = parts[1] ?? 0;
17
+ const seconds = parts[2] ?? 0;
18
+ result.setHours(hours, minutes, seconds, 0);
19
+ return result;
20
+ }
21
+ function getBlockedIntervalDisplayRange(interval, referenceDate) {
22
+ const startIsTimeOnly = typeof interval.start === "string" && isTimeOnlyFormat(interval.start);
23
+ const endIsTimeOnly = typeof interval.end === "string" && isTimeOnlyFormat(interval.end);
24
+ const baseDate = referenceDate ?? /* @__PURE__ */ new Date();
25
+ if (startIsTimeOnly && endIsTimeOnly) {
26
+ return {
27
+ start: combineDateAndTime(baseDate, interval.start),
28
+ end: combineDateAndTime(baseDate, interval.end)
29
+ };
30
+ }
31
+ return {
32
+ start: parseDate(interval.start),
33
+ end: parseDate(interval.end)
34
+ };
35
+ }
36
+ function getBlockedIntervalDisplayLabels(interval, options = {}) {
37
+ const { start, end } = getBlockedIntervalDisplayRange(interval, options.referenceDate);
38
+ const formatter = createSchedulerDateFormatter(options);
39
+ const titleLabel = interval.title ?? "Blocked interval";
40
+ const dateLabel = formatter.format(start, options.dateOptions ?? { weekday: "long", year: "numeric", month: "long", day: "numeric" });
41
+ const timeRangeLabel = formatTimeRange(start, end, formatter.config.locale, options.timeFormat, formatter.config.timeZone);
42
+ const rangeLabel = options.includeDate === false ? timeRangeLabel : `${dateLabel}, ${timeRangeLabel}`;
43
+ const summaryLabel = `${titleLabel}, ${rangeLabel}`;
44
+ return {
45
+ titleLabel,
46
+ dateLabel,
47
+ timeRangeLabel,
48
+ summaryLabel,
49
+ ariaLabel: `Blocked interval, ${summaryLabel}`
50
+ };
51
+ }
52
+ function addDays(date, days) {
53
+ const result = new Date(date);
54
+ result.setDate(result.getDate() + days);
55
+ return result;
56
+ }
57
+ function startOfDay(date) {
58
+ const result = new Date(date);
59
+ result.setHours(0, 0, 0, 0);
60
+ return result;
61
+ }
62
+ function endOfDay(date) {
63
+ const result = new Date(date);
64
+ result.setHours(23, 59, 59, 999);
65
+ return result;
66
+ }
67
+ function dateRangesOverlap(start1, end1, start2, end2) {
68
+ return start1 < end2 && start2 < end1;
69
+ }
70
+ function expandBlockedInterval(interval, rangeStart, rangeEnd, maxOccurrences = 365) {
71
+ const results = [];
72
+ const isStartTimeOnly = typeof interval.start === "string" && isTimeOnlyFormat(interval.start);
73
+ const isEndTimeOnly = typeof interval.end === "string" && isTimeOnlyFormat(interval.end);
74
+ if (interval.rrule) {
75
+ const rrule = typeof interval.rrule === "string" ? parseRRule(interval.rrule) : interval.rrule;
76
+ if (!rrule) return results;
77
+ const baseStart = isStartTimeOnly ? combineDateAndTime(rangeStart, interval.start) : parseDate(interval.start);
78
+ const baseDuration = isEndTimeOnly ? (() => {
79
+ const startTime = combineDateAndTime(new Date(2e3, 0, 1), interval.start);
80
+ const endTime = combineDateAndTime(new Date(2e3, 0, 1), interval.end);
81
+ return endTime.getTime() - startTime.getTime();
82
+ })() : parseDate(interval.end).getTime() - parseDate(interval.start).getTime();
83
+ const occurrences = expandRRuleForBlocked(rrule, baseStart, rangeStart, rangeEnd, interval.exdate, maxOccurrences);
84
+ for (const occStart of occurrences) {
85
+ const occEnd = new Date(occStart.getTime() + baseDuration);
86
+ if (dateRangesOverlap(occStart, occEnd, rangeStart, rangeEnd)) {
87
+ results.push({
88
+ id: `${interval.id}_${occStart.getTime()}`,
89
+ originalId: interval.id,
90
+ start: occStart,
91
+ end: occEnd,
92
+ resourceId: interval.resourceId,
93
+ resourceIds: interval.resourceIds,
94
+ title: interval.title,
95
+ className: interval.className,
96
+ background: interval.background,
97
+ isRecurring: true
98
+ });
99
+ }
100
+ }
101
+ } else if (isStartTimeOnly && isEndTimeOnly) {
102
+ let current = startOfDay(rangeStart);
103
+ while (current <= rangeEnd) {
104
+ const occStart = combineDateAndTime(current, interval.start);
105
+ const occEnd = combineDateAndTime(current, interval.end);
106
+ if (dateRangesOverlap(occStart, occEnd, rangeStart, rangeEnd)) {
107
+ results.push({
108
+ id: `${interval.id}_${occStart.getTime()}`,
109
+ originalId: interval.id,
110
+ start: occStart,
111
+ end: occEnd,
112
+ resourceId: interval.resourceId,
113
+ resourceIds: interval.resourceIds,
114
+ title: interval.title,
115
+ className: interval.className,
116
+ background: interval.background,
117
+ isRecurring: false
118
+ });
119
+ }
120
+ current = addDays(current, 1);
121
+ }
122
+ } else {
123
+ const start = parseDate(interval.start);
124
+ const end = parseDate(interval.end);
125
+ if (dateRangesOverlap(start, end, rangeStart, rangeEnd)) {
126
+ results.push({
127
+ id: `${interval.id}`,
128
+ originalId: interval.id,
129
+ start,
130
+ end,
131
+ resourceId: interval.resourceId,
132
+ resourceIds: interval.resourceIds,
133
+ title: interval.title,
134
+ className: interval.className,
135
+ background: interval.background,
136
+ isRecurring: false
137
+ });
138
+ }
139
+ }
140
+ return results;
141
+ }
142
+ function expandRRuleForBlocked(rrule, baseStart, rangeStart, rangeEnd, exdate, maxOccurrences = 365) {
143
+ const occurrences = [];
144
+ const exdates = /* @__PURE__ */ new Set();
145
+ if (exdate) {
146
+ for (const exd of exdate) {
147
+ const d = typeof exd === "string" ? new Date(exd) : exd;
148
+ exdates.add(`${d.getFullYear()}-${d.getMonth()}-${d.getDate()}`);
149
+ }
150
+ }
151
+ const interval = rrule.interval || 1;
152
+ const until = rrule.until ? typeof rrule.until === "string" ? new Date(rrule.until) : rrule.until : null;
153
+ const count = rrule.count;
154
+ let current = new Date(baseStart);
155
+ let totalCount = 0;
156
+ const effectiveEnd = until && until < rangeEnd ? until : rangeEnd;
157
+ const adjustedStart = new Date(rangeStart);
158
+ adjustedStart.setDate(adjustedStart.getDate() - 7);
159
+ while (current <= effectiveEnd && totalCount < maxOccurrences) {
160
+ if (count !== void 0 && totalCount >= count) break;
161
+ const matchingDates = getMatchingDatesForRRule(current, rrule, baseStart);
162
+ for (const date of matchingDates) {
163
+ if (count !== void 0 && totalCount >= count) break;
164
+ if (date > effectiveEnd) continue;
165
+ if (date < baseStart) continue;
166
+ const dateKey = `${date.getFullYear()}-${date.getMonth()}-${date.getDate()}`;
167
+ if (exdates.has(dateKey)) continue;
168
+ if (date >= adjustedStart && date <= rangeEnd) {
169
+ occurrences.push(new Date(date));
170
+ }
171
+ totalCount++;
172
+ }
173
+ current = advanceToNextPeriod(current, rrule.freq, interval);
174
+ }
175
+ return occurrences;
176
+ }
177
+ var WEEKDAY_MAP = {
178
+ SU: 0,
179
+ MO: 1,
180
+ TU: 2,
181
+ WE: 3,
182
+ TH: 4,
183
+ FR: 5,
184
+ SA: 6
185
+ };
186
+ var WEEKDAY_REVERSE = {
187
+ 0: "SU",
188
+ 1: "MO",
189
+ 2: "TU",
190
+ 3: "WE",
191
+ 4: "TH",
192
+ 5: "FR",
193
+ 6: "SA"
194
+ };
195
+ function getMatchingDatesForRRule(current, rrule, baseStart) {
196
+ const dates = [];
197
+ const { freq, byday } = rrule;
198
+ switch (freq) {
199
+ case "DAILY": {
200
+ dates.push(new Date(current));
201
+ break;
202
+ }
203
+ case "WEEKLY": {
204
+ if (byday && byday.length > 0) {
205
+ const weekStart = getWeekStart(current, 1);
206
+ for (let i = 0; i < 7; i++) {
207
+ const dayDate = addDays(weekStart, i);
208
+ const dayName = WEEKDAY_REVERSE[dayDate.getDay()];
209
+ if (byday.includes(dayName)) {
210
+ const occurrence = new Date(dayDate);
211
+ occurrence.setHours(baseStart.getHours(), baseStart.getMinutes(), baseStart.getSeconds(), baseStart.getMilliseconds());
212
+ dates.push(occurrence);
213
+ }
214
+ }
215
+ } else {
216
+ dates.push(new Date(current));
217
+ }
218
+ break;
219
+ }
220
+ case "MONTHLY": {
221
+ if (byday && byday.length > 0) {
222
+ for (const day of byday) {
223
+ const parsed = parsePositionalWeekday(day);
224
+ if (!parsed) continue;
225
+ const weekday = WEEKDAY_MAP[parsed.weekday];
226
+ if (parsed.position !== void 0) {
227
+ const matchDate = getWeekdayOfMonth(current, weekday, parsed.position);
228
+ if (matchDate) {
229
+ matchDate.setHours(baseStart.getHours(), baseStart.getMinutes(), baseStart.getSeconds(), baseStart.getMilliseconds());
230
+ dates.push(matchDate);
231
+ }
232
+ }
233
+ }
234
+ } else {
235
+ const dayOfMonth = baseStart.getDate();
236
+ const daysInMonth = getDaysInMonth(current.getFullYear(), current.getMonth());
237
+ const actualDay = Math.min(dayOfMonth, daysInMonth);
238
+ const occurrence = new Date(current.getFullYear(), current.getMonth(), actualDay);
239
+ occurrence.setHours(baseStart.getHours(), baseStart.getMinutes(), baseStart.getSeconds(), baseStart.getMilliseconds());
240
+ dates.push(occurrence);
241
+ }
242
+ break;
243
+ }
244
+ case "YEARLY": {
245
+ const year = current.getFullYear();
246
+ const occurrence = new Date(year, baseStart.getMonth(), baseStart.getDate());
247
+ occurrence.setHours(baseStart.getHours(), baseStart.getMinutes(), baseStart.getSeconds(), baseStart.getMilliseconds());
248
+ dates.push(occurrence);
249
+ break;
250
+ }
251
+ }
252
+ return dates;
253
+ }
254
+ function getWeekStart(date, wkst) {
255
+ const d = new Date(date);
256
+ const day = d.getDay();
257
+ const diff = (day - wkst + 7) % 7;
258
+ d.setDate(d.getDate() - diff);
259
+ d.setHours(0, 0, 0, 0);
260
+ return d;
261
+ }
262
+ function advanceToNextPeriod(date, freq, interval) {
263
+ const result = new Date(date);
264
+ switch (freq) {
265
+ case "DAILY":
266
+ result.setDate(result.getDate() + interval);
267
+ break;
268
+ case "WEEKLY":
269
+ result.setDate(result.getDate() + 7 * interval);
270
+ break;
271
+ case "MONTHLY":
272
+ result.setMonth(result.getMonth() + interval);
273
+ break;
274
+ case "YEARLY":
275
+ result.setFullYear(result.getFullYear() + interval);
276
+ break;
277
+ default:
278
+ result.setDate(result.getDate() + 1);
279
+ }
280
+ return result;
281
+ }
282
+ function parsePositionalWeekday(byday) {
283
+ const match = byday.match(/^(-?\d)?([A-Z]{2})$/);
284
+ if (!match) return null;
285
+ const position = match[1] ? parseInt(match[1], 10) : void 0;
286
+ const weekday = match[2];
287
+ return { weekday, position };
288
+ }
289
+ function getDaysInMonth(year, month) {
290
+ return new Date(year, month + 1, 0).getDate();
291
+ }
292
+ function getWeekdayOfMonth(date, weekday, position) {
293
+ const year = date.getFullYear();
294
+ const month = date.getMonth();
295
+ const daysInMonth = getDaysInMonth(year, month);
296
+ if (position > 0) {
297
+ let count = 0;
298
+ for (let day = 1; day <= daysInMonth; day++) {
299
+ const d = new Date(year, month, day);
300
+ if (d.getDay() === weekday) {
301
+ count++;
302
+ if (count === position) return d;
303
+ }
304
+ }
305
+ } else if (position < 0) {
306
+ let count = 0;
307
+ for (let day = daysInMonth; day >= 1; day--) {
308
+ const d = new Date(year, month, day);
309
+ if (d.getDay() === weekday) {
310
+ count--;
311
+ if (count === position) return d;
312
+ }
313
+ }
314
+ }
315
+ return null;
316
+ }
317
+ function getExpandedBlockedIntervals(options, rangeStart, rangeEnd) {
318
+ if (!options || !options.intervals || options.intervals.length === 0) {
319
+ return [];
320
+ }
321
+ const results = [];
322
+ for (const interval of options.intervals) {
323
+ const expanded = expandBlockedInterval(interval, rangeStart, rangeEnd);
324
+ results.push(...expanded);
325
+ }
326
+ return results;
327
+ }
328
+ function getBlockedIntervalsForDay(options, date, resourceId) {
329
+ const dayStart = startOfDay(date);
330
+ const dayEnd = endOfDay(date);
331
+ const intervals = getExpandedBlockedIntervals(options, dayStart, dayEnd);
332
+ if (resourceId !== void 0) {
333
+ return intervals.filter((interval) => {
334
+ if (!interval.resourceId && !interval.resourceIds) return true;
335
+ if (interval.resourceId === resourceId) return true;
336
+ if (interval.resourceIds && interval.resourceIds.includes(resourceId)) return true;
337
+ return false;
338
+ });
339
+ }
340
+ return intervals.filter((interval) => !interval.resourceId && !interval.resourceIds);
341
+ }
342
+ function isTimeWithinBlockedInterval(date, options, resourceId) {
343
+ const intervals = getBlockedIntervalsForDay(options, date, resourceId);
344
+ return intervals.some((interval) => {
345
+ return date >= interval.start && date < interval.end;
346
+ });
347
+ }
348
+ function isRangeWithinBlockedInterval(start, end, options, resourceId) {
349
+ if (!options || !options.intervals || options.intervals.length === 0) {
350
+ return false;
351
+ }
352
+ const intervals = getExpandedBlockedIntervals(options, start, end);
353
+ const filteredIntervals = resourceId !== void 0 ? intervals.filter((interval) => !interval.resourceId && !interval.resourceIds || interval.resourceId === resourceId || interval.resourceIds && interval.resourceIds.includes(resourceId)) : intervals.filter((interval) => !interval.resourceId && !interval.resourceIds);
354
+ return filteredIntervals.some((interval) => {
355
+ return dateRangesOverlap(start, end, interval.start, interval.end);
356
+ });
357
+ }
358
+ function canDropWithBlockedIntervals(start, end, _allDay, _view, options, resourceId) {
359
+ if (!options) return true;
360
+ if (options.preventDragInto === false && options.allowOverlap === true) {
361
+ return true;
362
+ }
363
+ if (options.preventDragInto !== false) {
364
+ if (isRangeWithinBlockedInterval(start, end, options, resourceId)) {
365
+ return false;
366
+ }
367
+ }
368
+ return true;
369
+ }
370
+ function canCreateWithBlockedIntervals(start, end, options, resourceId) {
371
+ if (!options) return true;
372
+ if (options.preventCreate === false) return true;
373
+ return !isRangeWithinBlockedInterval(start, end, options, resourceId);
374
+ }
375
+
376
+ // src/utils/constraints.ts
377
+ var DEFAULT_BUSINESS_HOURS = {
378
+ daysOfWeek: [1, 2, 3, 4, 5],
379
+ startTime: "09:00",
380
+ endTime: "17:00"
381
+ };
382
+ function normalizeBusinessHours(businessHours) {
383
+ if (businessHours === false) {
384
+ return [];
385
+ }
386
+ if (businessHours === true) {
387
+ return [DEFAULT_BUSINESS_HOURS];
388
+ }
389
+ if (Array.isArray(businessHours)) {
390
+ return businessHours;
391
+ }
392
+ return [businessHours];
393
+ }
394
+ function isWithinBusinessHours(date, businessHours) {
395
+ const configs = normalizeBusinessHours(businessHours);
396
+ if (configs.length === 0) {
397
+ return true;
398
+ }
399
+ const dayOfWeek = date.getDay();
400
+ const timeMinutes = date.getHours() * 60 + date.getMinutes();
401
+ return configs.some((config) => {
402
+ if (!config.daysOfWeek.includes(dayOfWeek)) {
403
+ return false;
404
+ }
405
+ const startMinutes = timeStringToMinutes(config.startTime);
406
+ const endMinutes = timeStringToMinutes(config.endTime);
407
+ return timeMinutes >= startMinutes && timeMinutes < endMinutes;
408
+ });
409
+ }
410
+ function isRangeWithinBusinessHours(start, end, businessHours) {
411
+ const configs = normalizeBusinessHours(businessHours);
412
+ if (configs.length === 0) {
413
+ return true;
414
+ }
415
+ const startDayOfWeek = start.getDay();
416
+ const endDayOfWeek = end.getDay();
417
+ if (startDayOfWeek !== endDayOfWeek) {
418
+ return false;
419
+ }
420
+ const startMinutes = start.getHours() * 60 + start.getMinutes();
421
+ const endMinutes = end.getHours() * 60 + end.getMinutes();
422
+ return configs.some((config) => {
423
+ if (!config.daysOfWeek.includes(startDayOfWeek)) {
424
+ return false;
425
+ }
426
+ const businessStart = timeStringToMinutes(config.startTime);
427
+ const businessEnd = timeStringToMinutes(config.endTime);
428
+ return startMinutes >= businessStart && endMinutes <= businessEnd;
429
+ });
430
+ }
431
+ function isTimeSlotInBusinessHours(date, slotDuration, businessHours) {
432
+ const configs = normalizeBusinessHours(businessHours);
433
+ if (configs.length === 0) {
434
+ return false;
435
+ }
436
+ const dayOfWeek = date.getDay();
437
+ const slotStartMinutes = date.getHours() * 60 + date.getMinutes();
438
+ const slotEndMinutes = slotStartMinutes + slotDuration;
439
+ return configs.some((config) => {
440
+ if (!config.daysOfWeek.includes(dayOfWeek)) {
441
+ return false;
442
+ }
443
+ const businessStart = timeStringToMinutes(config.startTime);
444
+ const businessEnd = timeStringToMinutes(config.endTime);
445
+ return slotStartMinutes >= businessStart && slotEndMinutes <= businessEnd;
446
+ });
447
+ }
448
+ function getBusinessHoursForDay(dayOfWeek, businessHours) {
449
+ const configs = normalizeBusinessHours(businessHours);
450
+ for (const config of configs) {
451
+ if (config.daysOfWeek.includes(dayOfWeek)) {
452
+ return {
453
+ start: config.startTime,
454
+ end: config.endTime
455
+ };
456
+ }
457
+ }
458
+ return null;
459
+ }
460
+ function isDateWithinConstraint(date, constraint) {
461
+ if (!constraint) {
462
+ return true;
463
+ }
464
+ const dayOfWeek = date.getDay();
465
+ if (constraint.daysOfWeek && !constraint.daysOfWeek.includes(dayOfWeek)) {
466
+ return false;
467
+ }
468
+ const timeMinutes = date.getHours() * 60 + date.getMinutes();
469
+ if (constraint.startTime) {
470
+ const startMinutes = timeStringToMinutes(constraint.startTime);
471
+ if (timeMinutes < startMinutes) {
472
+ return false;
473
+ }
474
+ }
475
+ if (constraint.endTime) {
476
+ const endMinutes = timeStringToMinutes(constraint.endTime);
477
+ if (timeMinutes > endMinutes) {
478
+ return false;
479
+ }
480
+ }
481
+ return true;
482
+ }
483
+ function canSelect(start, end, allDay, view, selectConstraint, selectAllow) {
484
+ if (selectConstraint) {
485
+ if (!isDateWithinConstraint(start, selectConstraint)) {
486
+ return false;
487
+ }
488
+ if (!isDateWithinConstraint(end, selectConstraint)) {
489
+ return false;
490
+ }
491
+ }
492
+ if (selectAllow) {
493
+ const selectInfo = { start, end, allDay, view };
494
+ if (!selectAllow(selectInfo)) {
495
+ return false;
496
+ }
497
+ }
498
+ return true;
499
+ }
500
+ function canDropEvent(start, end, allDay, view, event, eventConstraint, eventAllow, businessHours, blockedIntervals, resourceId) {
501
+ if (eventConstraint) {
502
+ if (eventConstraint === "businessHours") {
503
+ if (!isRangeWithinBusinessHours(start, end, businessHours)) {
504
+ return false;
505
+ }
506
+ } else if (eventConstraint === "blockedIntervals") {
507
+ if (isRangeWithinBlockedInterval(start, end, blockedIntervals, resourceId)) {
508
+ return false;
509
+ }
510
+ } else {
511
+ if (!isDateWithinConstraint(start, eventConstraint)) {
512
+ return false;
513
+ }
514
+ if (!isDateWithinConstraint(end, eventConstraint)) {
515
+ return false;
516
+ }
517
+ }
518
+ }
519
+ if (blockedIntervals && blockedIntervals.preventDragInto !== false) {
520
+ if (isRangeWithinBlockedInterval(start, end, blockedIntervals, resourceId)) {
521
+ return false;
522
+ }
523
+ }
524
+ if (eventAllow) {
525
+ const dropInfo = { start, end, allDay, view, resourceId };
526
+ if (!eventAllow(dropInfo, event)) {
527
+ return false;
528
+ }
529
+ }
530
+ return true;
531
+ }
532
+ function getTimeSlotBusinessHoursInfo(date, slotDuration, businessHours) {
533
+ const configs = normalizeBusinessHours(businessHours);
534
+ if (configs.length === 0) {
535
+ return { isBusinessHour: false, isBusinessStart: false, isBusinessEnd: false };
536
+ }
537
+ const dayOfWeek = date.getDay();
538
+ const slotStartMinutes = date.getHours() * 60 + date.getMinutes();
539
+ const slotEndMinutes = slotStartMinutes + slotDuration;
540
+ for (const config of configs) {
541
+ if (!config.daysOfWeek.includes(dayOfWeek)) {
542
+ continue;
543
+ }
544
+ const businessStart = timeStringToMinutes(config.startTime);
545
+ const businessEnd = timeStringToMinutes(config.endTime);
546
+ const isWithin = slotStartMinutes >= businessStart && slotEndMinutes <= businessEnd;
547
+ if (isWithin) {
548
+ return {
549
+ isBusinessHour: true,
550
+ isBusinessStart: slotStartMinutes === businessStart,
551
+ isBusinessEnd: slotEndMinutes === businessEnd
552
+ };
553
+ }
554
+ }
555
+ return { isBusinessHour: false, isBusinessStart: false, isBusinessEnd: false };
556
+ }
557
+
558
+ export { DEFAULT_BUSINESS_HOURS, canCreateWithBlockedIntervals, canDropEvent, canDropWithBlockedIntervals, canSelect, expandBlockedInterval, getBlockedIntervalDisplayLabels, getBlockedIntervalsForDay, getBusinessHoursForDay, getExpandedBlockedIntervals, getTimeSlotBusinessHoursInfo, isDateWithinConstraint, isRangeWithinBlockedInterval, isRangeWithinBusinessHours, isTimeSlotInBusinessHours, isTimeWithinBlockedInterval, isWithinBusinessHours, normalizeBusinessHours };