gantt-lib 0.76.0 → 0.78.0

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.
package/dist/index.js CHANGED
@@ -8,9 +8,6 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
8
8
  var __getOwnPropNames = Object.getOwnPropertyNames;
9
9
  var __getProtoOf = Object.getPrototypeOf;
10
10
  var __hasOwnProp = Object.prototype.hasOwnProperty;
11
- var __esm = (fn, res) => function __init() {
12
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
13
- };
14
11
  var __export = (target, all) => {
15
12
  for (var name in all)
16
13
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -33,474 +30,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
33
30
  ));
34
31
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
35
32
 
36
- // src/core/scheduling/dateMath.ts
37
- function normalizeUTCDate(date) {
38
- return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()));
39
- }
40
- function parseDateOnly(date) {
41
- const parsed = typeof date === "string" ? /* @__PURE__ */ new Date(`${date.split("T")[0]}T00:00:00.000Z`) : normalizeUTCDate(date);
42
- return normalizeUTCDate(parsed);
43
- }
44
- function getBusinessDayOffset(fromDate, toDate, weekendPredicate) {
45
- const from = normalizeUTCDate(fromDate);
46
- const to = normalizeUTCDate(toDate);
47
- if (from.getTime() === to.getTime()) {
48
- return 0;
49
- }
50
- const step = to.getTime() > from.getTime() ? 1 : -1;
51
- const current = new Date(from);
52
- let offset = 0;
53
- while (current.getTime() !== to.getTime()) {
54
- current.setUTCDate(current.getUTCDate() + step);
55
- if (!weekendPredicate(current)) {
56
- offset += step;
57
- }
58
- }
59
- return offset;
60
- }
61
- function shiftBusinessDayOffset(date, offset, weekendPredicate) {
62
- const current = normalizeUTCDate(date);
63
- if (offset === 0) {
64
- return current;
65
- }
66
- const step = offset > 0 ? 1 : -1;
67
- let remaining = Math.abs(offset);
68
- while (remaining > 0) {
69
- current.setUTCDate(current.getUTCDate() + step);
70
- if (!weekendPredicate(current)) {
71
- remaining--;
72
- }
73
- }
74
- return current;
75
- }
76
- function getBusinessDaysCount(startDate, endDate, weekendPredicate) {
77
- const start = typeof startDate === "string" ? /* @__PURE__ */ new Date(`${startDate.split("T")[0]}T00:00:00.000Z`) : normalizeUTCDate(startDate);
78
- const end = typeof endDate === "string" ? /* @__PURE__ */ new Date(`${endDate.split("T")[0]}T00:00:00.000Z`) : normalizeUTCDate(endDate);
79
- let count = 0;
80
- const current = new Date(start);
81
- while (current.getTime() <= end.getTime()) {
82
- if (!weekendPredicate(current)) {
83
- count++;
84
- }
85
- current.setUTCDate(current.getUTCDate() + 1);
86
- }
87
- return Math.max(1, count);
88
- }
89
- function addBusinessDays(startDate, businessDays, weekendPredicate) {
90
- const start = typeof startDate === "string" ? /* @__PURE__ */ new Date(`${startDate.split("T")[0]}T00:00:00.000Z`) : normalizeUTCDate(startDate);
91
- const current = new Date(start);
92
- let targetDays = Math.max(1, businessDays);
93
- let businessDaysCounted = 0;
94
- while (businessDaysCounted < targetDays) {
95
- if (!weekendPredicate(current)) {
96
- businessDaysCounted++;
97
- }
98
- if (businessDaysCounted < targetDays) {
99
- current.setUTCDate(current.getUTCDate() + 1);
100
- }
101
- }
102
- return current;
103
- }
104
- function subtractBusinessDays(endDate, businessDays, weekendPredicate) {
105
- const end = typeof endDate === "string" ? /* @__PURE__ */ new Date(`${endDate.split("T")[0]}T00:00:00.000Z`) : normalizeUTCDate(endDate);
106
- const current = new Date(end);
107
- let targetDays = Math.max(1, businessDays);
108
- let businessDaysCounted = 0;
109
- while (businessDaysCounted < targetDays) {
110
- if (!weekendPredicate(current)) {
111
- businessDaysCounted++;
112
- }
113
- if (businessDaysCounted < targetDays) {
114
- current.setUTCDate(current.getUTCDate() - 1);
115
- }
116
- }
117
- return current;
118
- }
119
- function alignToWorkingDay(date, direction, weekendPredicate) {
120
- const current = normalizeUTCDate(date);
121
- while (weekendPredicate(current)) {
122
- current.setUTCDate(current.getUTCDate() + direction);
123
- }
124
- return current;
125
- }
126
- function getTaskDuration(startDate, endDate, businessDays = false, weekendPredicate) {
127
- const start = parseDateOnly(startDate);
128
- const end = parseDateOnly(endDate);
129
- if (businessDays && weekendPredicate) {
130
- return getBusinessDaysCount(start, end, weekendPredicate);
131
- }
132
- return Math.max(1, Math.round((end.getTime() - start.getTime()) / DAY_MS) + 1);
133
- }
134
- var DAY_MS;
135
- var init_dateMath = __esm({
136
- "src/core/scheduling/dateMath.ts"() {
137
- "use strict";
138
- DAY_MS = 24 * 60 * 60 * 1e3;
139
- }
140
- });
141
-
142
- // src/utils/dateUtils.ts
143
- var dateUtils_exports = {};
144
- __export(dateUtils_exports, {
145
- addBusinessDays: () => addBusinessDays2,
146
- createCustomDayPredicate: () => createCustomDayPredicate,
147
- createDateKey: () => createDateKey,
148
- formatDateLabel: () => formatDateLabel,
149
- formatDateRangeLabel: () => formatDateRangeLabel,
150
- getBusinessDaysCount: () => getBusinessDaysCount2,
151
- getDayOffset: () => getDayOffset,
152
- getMonthBlocks: () => getMonthBlocks,
153
- getMonthDays: () => getMonthDays,
154
- getMonthSpans: () => getMonthSpans,
155
- getMultiMonthDays: () => getMultiMonthDays,
156
- getWeekBlocks: () => getWeekBlocks,
157
- getWeekSpans: () => getWeekSpans,
158
- getYearSpans: () => getYearSpans,
159
- isToday: () => isToday,
160
- isWeekend: () => isWeekend,
161
- normalizeTaskDates: () => normalizeTaskDates,
162
- parseUTCDate: () => parseUTCDate,
163
- subtractBusinessDays: () => subtractBusinessDays2
164
- });
165
- function getBusinessDaysCount2(startDate, endDate, weekendPredicate) {
166
- return getBusinessDaysCount(startDate, endDate, weekendPredicate);
167
- }
168
- function addBusinessDays2(startDate, businessDays, weekendPredicate) {
169
- const result = addBusinessDays(startDate, businessDays, weekendPredicate);
170
- return result.toISOString().split("T")[0];
171
- }
172
- function subtractBusinessDays2(endDate, businessDays, weekendPredicate) {
173
- const result = subtractBusinessDays(endDate, businessDays, weekendPredicate);
174
- return result.toISOString().split("T")[0];
175
- }
176
- var parseUTCDate, getMonthDays, getDayOffset, isToday, isWeekend, createDateKey, createCustomDayPredicate, getMultiMonthDays, getMonthSpans, formatDateLabel, MONTH_ABBR, formatDateRangeLabel, getWeekBlocks, getWeekSpans, getMonthBlocks, getYearSpans, normalizeTaskDates;
177
- var init_dateUtils = __esm({
178
- "src/utils/dateUtils.ts"() {
179
- "use strict";
180
- init_dateMath();
181
- parseUTCDate = (date) => {
182
- if (typeof date === "string") {
183
- const dateStr = date.includes("T") ? date : `${date}T00:00:00Z`;
184
- const parsed = new Date(dateStr);
185
- if (isNaN(parsed.getTime())) {
186
- throw new Error(`Invalid date string: ${date}`);
187
- }
188
- return parsed;
189
- }
190
- return date;
191
- };
192
- getMonthDays = (date) => {
193
- const utcDate = parseUTCDate(date);
194
- const year = utcDate.getUTCFullYear();
195
- const month = utcDate.getUTCMonth();
196
- const daysInMonth = new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
197
- const days = [];
198
- for (let day = 1; day <= daysInMonth; day++) {
199
- days.push(new Date(Date.UTC(year, month, day)));
200
- }
201
- return days;
202
- };
203
- getDayOffset = (date, monthStart) => {
204
- const dateMs = Date.UTC(
205
- date.getUTCFullYear(),
206
- date.getUTCMonth(),
207
- date.getUTCDate()
208
- );
209
- const startMs = Date.UTC(
210
- monthStart.getUTCFullYear(),
211
- monthStart.getUTCMonth(),
212
- monthStart.getUTCDate()
213
- );
214
- return Math.round((dateMs - startMs) / (1e3 * 60 * 60 * 24));
215
- };
216
- isToday = (date) => {
217
- const now = /* @__PURE__ */ new Date();
218
- const today = new Date(Date.UTC(
219
- now.getFullYear(),
220
- now.getMonth(),
221
- now.getDate()
222
- ));
223
- const compareDate = new Date(Date.UTC(
224
- date.getUTCFullYear(),
225
- date.getUTCMonth(),
226
- date.getUTCDate()
227
- ));
228
- return today.getTime() === compareDate.getTime();
229
- };
230
- isWeekend = (date) => {
231
- const day = date.getUTCDay();
232
- return day === 0 || day === 6;
233
- };
234
- createDateKey = (date) => {
235
- return `${date.getUTCFullYear()}-${date.getUTCMonth()}-${date.getUTCDate()}`;
236
- };
237
- createCustomDayPredicate = (config) => {
238
- const { customDays, isWeekend: basePredicate } = config;
239
- const workdaySet = /* @__PURE__ */ new Set();
240
- const weekendSet = /* @__PURE__ */ new Set();
241
- if (customDays && customDays.length > 0) {
242
- for (const item of customDays) {
243
- const key = createDateKey(item.date);
244
- if (item.type === "workday") {
245
- workdaySet.add(key);
246
- } else {
247
- weekendSet.add(key);
248
- }
249
- }
250
- }
251
- return (date) => {
252
- const key = createDateKey(date);
253
- if (workdaySet.has(key)) {
254
- return false;
255
- }
256
- if (weekendSet.has(key)) {
257
- return true;
258
- }
259
- if (basePredicate) {
260
- return basePredicate(date);
261
- }
262
- const dayOfWeek = date.getUTCDay();
263
- return dayOfWeek === 0 || dayOfWeek === 6;
264
- };
265
- };
266
- getMultiMonthDays = (tasks) => {
267
- if (!tasks || tasks.length === 0) {
268
- return getMonthDays(/* @__PURE__ */ new Date());
269
- }
270
- let minDate = null;
271
- let maxDate = null;
272
- for (const task of tasks) {
273
- const start = parseUTCDate(task.startDate);
274
- const end = parseUTCDate(task.endDate);
275
- if (!minDate || start.getTime() < minDate.getTime()) {
276
- minDate = start;
277
- }
278
- if (!maxDate || end.getTime() > maxDate.getTime()) {
279
- maxDate = end;
280
- }
281
- }
282
- if (!minDate || !maxDate) {
283
- return getMonthDays(/* @__PURE__ */ new Date());
284
- }
285
- const startOfMonth2 = new Date(Date.UTC(
286
- minDate.getUTCFullYear(),
287
- minDate.getUTCMonth(),
288
- 1
289
- ));
290
- const endOfMonth = new Date(Date.UTC(
291
- maxDate.getUTCFullYear(),
292
- maxDate.getUTCMonth() + 1 + 2,
293
- // Original + 2 months padding after
294
- 0
295
- ));
296
- const days = [];
297
- const current = new Date(startOfMonth2);
298
- while (current.getTime() <= endOfMonth.getTime()) {
299
- days.push(new Date(Date.UTC(
300
- current.getUTCFullYear(),
301
- current.getUTCMonth(),
302
- current.getUTCDate()
303
- )));
304
- current.setUTCDate(current.getUTCDate() + 1);
305
- }
306
- return days;
307
- };
308
- getMonthSpans = (dateRange) => {
309
- if (dateRange.length === 0) {
310
- return [];
311
- }
312
- const spans = [];
313
- let currentMonthYear = `${dateRange[0].getUTCFullYear()}-${dateRange[0].getUTCMonth()}`;
314
- let startOfMonthIndex = 0;
315
- for (let i = 0; i < dateRange.length; i++) {
316
- const date = dateRange[i];
317
- const monthYear = `${date.getUTCFullYear()}-${date.getUTCMonth()}`;
318
- if (monthYear !== currentMonthYear) {
319
- spans.push({
320
- month: new Date(Date.UTC(
321
- dateRange[startOfMonthIndex].getUTCFullYear(),
322
- dateRange[startOfMonthIndex].getUTCMonth(),
323
- 1
324
- )),
325
- days: i - startOfMonthIndex,
326
- startIndex: startOfMonthIndex
327
- });
328
- currentMonthYear = monthYear;
329
- startOfMonthIndex = i;
330
- }
331
- if (i === dateRange.length - 1) {
332
- spans.push({
333
- month: new Date(Date.UTC(
334
- date.getUTCFullYear(),
335
- date.getUTCMonth(),
336
- 1
337
- )),
338
- days: i - startOfMonthIndex + 1,
339
- startIndex: startOfMonthIndex
340
- });
341
- }
342
- }
343
- return spans;
344
- };
345
- formatDateLabel = (date) => {
346
- const parsed = parseUTCDate(date);
347
- const day = String(parsed.getUTCDate()).padStart(2, "0");
348
- const month = String(parsed.getUTCMonth() + 1).padStart(2, "0");
349
- return `${day}.${month}`;
350
- };
351
- MONTH_ABBR = [
352
- "\u044F\u043D\u0432",
353
- "\u0444\u0435\u0432",
354
- "\u043C\u0430\u0440",
355
- "\u0430\u043F\u0440",
356
- "\u043C\u0430\u044F",
357
- "\u0438\u044E\u043D",
358
- "\u0438\u044E\u043B",
359
- "\u0430\u0432\u0433",
360
- "\u0441\u0435\u043D",
361
- "\u043E\u043A\u0442",
362
- "\u043D\u043E\u044F",
363
- "\u0434\u0435\u043A"
364
- ];
365
- formatDateRangeLabel = (startDate, endDate) => {
366
- const start = parseUTCDate(startDate);
367
- const end = parseUTCDate(endDate);
368
- const startDay = start.getUTCDate();
369
- const endDay = end.getUTCDate();
370
- const startMonth = start.getUTCMonth();
371
- const endMonth = end.getUTCMonth();
372
- const startYear = start.getUTCFullYear();
373
- const endYear = end.getUTCFullYear();
374
- if (startMonth === endMonth && startYear === endYear) {
375
- if (startDay === endDay) {
376
- return `${startDay} ${MONTH_ABBR[startMonth]}`;
377
- }
378
- return `${startDay}\u2013${endDay} ${MONTH_ABBR[startMonth]}`;
379
- }
380
- if (startYear === endYear) {
381
- return `${startDay} ${MONTH_ABBR[startMonth]}\u2013${endDay} ${MONTH_ABBR[endMonth]}`;
382
- }
383
- return `${startDay} ${MONTH_ABBR[startMonth]} ${startYear}\u2013${endDay} ${MONTH_ABBR[endMonth]} ${endYear}`;
384
- };
385
- getWeekBlocks = (days) => {
386
- if (days.length === 0) return [];
387
- const blocks = [];
388
- let blockStart = 0;
389
- while (blockStart < days.length) {
390
- const maxBlockEnd = Math.min(blockStart + 7, days.length);
391
- const startMonthYear = `${days[blockStart].getUTCFullYear()}-${days[blockStart].getUTCMonth()}`;
392
- let actualBlockEnd = blockStart + 7;
393
- if (actualBlockEnd > days.length) {
394
- actualBlockEnd = days.length;
395
- }
396
- for (let i = blockStart + 1; i < maxBlockEnd; i++) {
397
- const monthYear = `${days[i].getUTCFullYear()}-${days[i].getUTCMonth()}`;
398
- if (monthYear !== startMonthYear) {
399
- actualBlockEnd = i;
400
- break;
401
- }
402
- }
403
- blocks.push({
404
- startDate: days[blockStart],
405
- days: actualBlockEnd - blockStart
406
- });
407
- blockStart = actualBlockEnd;
408
- }
409
- return blocks;
410
- };
411
- getWeekSpans = (days) => {
412
- const blocks = getWeekBlocks(days);
413
- if (blocks.length === 0) return [];
414
- const spans = [];
415
- let currentMonthYear = `${blocks[0].startDate.getUTCFullYear()}-${blocks[0].startDate.getUTCMonth()}`;
416
- let startIndex = 0;
417
- let totalDays = 0;
418
- for (let i = 0; i < blocks.length; i++) {
419
- const block = blocks[i];
420
- const monthYear = `${block.startDate.getUTCFullYear()}-${block.startDate.getUTCMonth()}`;
421
- if (monthYear !== currentMonthYear) {
422
- spans.push({
423
- month: new Date(Date.UTC(
424
- blocks[startIndex].startDate.getUTCFullYear(),
425
- blocks[startIndex].startDate.getUTCMonth(),
426
- 1
427
- )),
428
- days: totalDays,
429
- startIndex
430
- });
431
- currentMonthYear = monthYear;
432
- startIndex = i;
433
- totalDays = 0;
434
- }
435
- totalDays += block.days;
436
- if (i === blocks.length - 1) {
437
- spans.push({
438
- month: new Date(Date.UTC(
439
- block.startDate.getUTCFullYear(),
440
- block.startDate.getUTCMonth(),
441
- 1
442
- )),
443
- days: totalDays,
444
- startIndex
445
- });
446
- }
447
- }
448
- return spans;
449
- };
450
- getMonthBlocks = (days) => {
451
- if (days.length === 0) return [];
452
- return getMonthSpans(days).map((span) => ({
453
- startDate: span.month,
454
- days: span.days
455
- }));
456
- };
457
- getYearSpans = (days) => {
458
- const blocks = getMonthBlocks(days);
459
- if (blocks.length === 0) return [];
460
- const spans = [];
461
- let currentYear = blocks[0].startDate.getUTCFullYear();
462
- let startIndex = 0;
463
- let totalDays = 0;
464
- for (let i = 0; i < blocks.length; i++) {
465
- const blockYear = blocks[i].startDate.getUTCFullYear();
466
- if (blockYear !== currentYear) {
467
- spans.push({
468
- year: new Date(Date.UTC(currentYear, 0, 1)),
469
- days: totalDays,
470
- startIndex
471
- });
472
- currentYear = blockYear;
473
- startIndex = i;
474
- totalDays = 0;
475
- }
476
- totalDays += blocks[i].days;
477
- if (i === blocks.length - 1) {
478
- spans.push({
479
- year: new Date(Date.UTC(currentYear, 0, 1)),
480
- days: totalDays,
481
- startIndex
482
- });
483
- }
484
- }
485
- return spans;
486
- };
487
- normalizeTaskDates = (startDate, endDate) => {
488
- const start = parseUTCDate(startDate);
489
- const end = parseUTCDate(endDate);
490
- if (end.getTime() < start.getTime()) {
491
- return {
492
- startDate: end.toISOString().split("T")[0],
493
- endDate: start.toISOString().split("T")[0]
494
- };
495
- }
496
- return {
497
- startDate: start.toISOString().split("T")[0],
498
- endDate: end.toISOString().split("T")[0]
499
- };
500
- };
501
- }
502
- });
503
-
504
33
  // src/index.ts
505
34
  var index_exports = {};
506
35
  __export(index_exports, {
@@ -613,13 +142,441 @@ module.exports = __toCommonJS(index_exports);
613
142
 
614
143
  // src/components/GanttChart/GanttChart.tsx
615
144
  var import_react15 = require("react");
616
- init_dateUtils();
617
145
 
618
- // src/core/scheduling/index.ts
619
- init_dateMath();
146
+ // src/core/scheduling/dateMath.ts
147
+ var DAY_MS = 24 * 60 * 60 * 1e3;
148
+ function normalizeUTCDate(date) {
149
+ return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()));
150
+ }
151
+ function parseDateOnly(date) {
152
+ const parsed = typeof date === "string" ? /* @__PURE__ */ new Date(`${date.split("T")[0]}T00:00:00.000Z`) : normalizeUTCDate(date);
153
+ return normalizeUTCDate(parsed);
154
+ }
155
+ function getBusinessDayOffset(fromDate, toDate, weekendPredicate) {
156
+ const from = normalizeUTCDate(fromDate);
157
+ const to = normalizeUTCDate(toDate);
158
+ if (from.getTime() === to.getTime()) {
159
+ return 0;
160
+ }
161
+ const step = to.getTime() > from.getTime() ? 1 : -1;
162
+ const current = new Date(from);
163
+ let offset = 0;
164
+ while (current.getTime() !== to.getTime()) {
165
+ current.setUTCDate(current.getUTCDate() + step);
166
+ if (!weekendPredicate(current)) {
167
+ offset += step;
168
+ }
169
+ }
170
+ return offset;
171
+ }
172
+ function shiftBusinessDayOffset(date, offset, weekendPredicate) {
173
+ const current = normalizeUTCDate(date);
174
+ if (offset === 0) {
175
+ return current;
176
+ }
177
+ const step = offset > 0 ? 1 : -1;
178
+ let remaining = Math.abs(offset);
179
+ while (remaining > 0) {
180
+ current.setUTCDate(current.getUTCDate() + step);
181
+ if (!weekendPredicate(current)) {
182
+ remaining--;
183
+ }
184
+ }
185
+ return current;
186
+ }
187
+ function getBusinessDaysCount(startDate, endDate, weekendPredicate) {
188
+ const start = typeof startDate === "string" ? /* @__PURE__ */ new Date(`${startDate.split("T")[0]}T00:00:00.000Z`) : normalizeUTCDate(startDate);
189
+ const end = typeof endDate === "string" ? /* @__PURE__ */ new Date(`${endDate.split("T")[0]}T00:00:00.000Z`) : normalizeUTCDate(endDate);
190
+ let count = 0;
191
+ const current = new Date(start);
192
+ while (current.getTime() <= end.getTime()) {
193
+ if (!weekendPredicate(current)) {
194
+ count++;
195
+ }
196
+ current.setUTCDate(current.getUTCDate() + 1);
197
+ }
198
+ return Math.max(1, count);
199
+ }
200
+ function addBusinessDays(startDate, businessDays, weekendPredicate) {
201
+ const start = typeof startDate === "string" ? /* @__PURE__ */ new Date(`${startDate.split("T")[0]}T00:00:00.000Z`) : normalizeUTCDate(startDate);
202
+ const current = new Date(start);
203
+ let targetDays = Math.max(1, businessDays);
204
+ let businessDaysCounted = 0;
205
+ while (businessDaysCounted < targetDays) {
206
+ if (!weekendPredicate(current)) {
207
+ businessDaysCounted++;
208
+ }
209
+ if (businessDaysCounted < targetDays) {
210
+ current.setUTCDate(current.getUTCDate() + 1);
211
+ }
212
+ }
213
+ return current;
214
+ }
215
+ function subtractBusinessDays(endDate, businessDays, weekendPredicate) {
216
+ const end = typeof endDate === "string" ? /* @__PURE__ */ new Date(`${endDate.split("T")[0]}T00:00:00.000Z`) : normalizeUTCDate(endDate);
217
+ const current = new Date(end);
218
+ let targetDays = Math.max(1, businessDays);
219
+ let businessDaysCounted = 0;
220
+ while (businessDaysCounted < targetDays) {
221
+ if (!weekendPredicate(current)) {
222
+ businessDaysCounted++;
223
+ }
224
+ if (businessDaysCounted < targetDays) {
225
+ current.setUTCDate(current.getUTCDate() - 1);
226
+ }
227
+ }
228
+ return current;
229
+ }
230
+ function alignToWorkingDay(date, direction, weekendPredicate) {
231
+ const current = normalizeUTCDate(date);
232
+ while (weekendPredicate(current)) {
233
+ current.setUTCDate(current.getUTCDate() + direction);
234
+ }
235
+ return current;
236
+ }
237
+ function getTaskDuration(startDate, endDate, businessDays = false, weekendPredicate) {
238
+ const start = parseDateOnly(startDate);
239
+ const end = parseDateOnly(endDate);
240
+ if (businessDays && weekendPredicate) {
241
+ return getBusinessDaysCount(start, end, weekendPredicate);
242
+ }
243
+ return Math.max(1, Math.round((end.getTime() - start.getTime()) / DAY_MS) + 1);
244
+ }
245
+
246
+ // src/utils/dateUtils.ts
247
+ var parseUTCDate = (date) => {
248
+ if (typeof date === "string") {
249
+ const dateStr = date.includes("T") ? date : `${date}T00:00:00Z`;
250
+ const parsed = new Date(dateStr);
251
+ if (isNaN(parsed.getTime())) {
252
+ throw new Error(`Invalid date string: ${date}`);
253
+ }
254
+ return parsed;
255
+ }
256
+ return date;
257
+ };
258
+ var getMonthDays = (date) => {
259
+ const utcDate = parseUTCDate(date);
260
+ const year = utcDate.getUTCFullYear();
261
+ const month = utcDate.getUTCMonth();
262
+ const daysInMonth = new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
263
+ const days = [];
264
+ for (let day = 1; day <= daysInMonth; day++) {
265
+ days.push(new Date(Date.UTC(year, month, day)));
266
+ }
267
+ return days;
268
+ };
269
+ var getDayOffset = (date, monthStart) => {
270
+ const dateMs = Date.UTC(
271
+ date.getUTCFullYear(),
272
+ date.getUTCMonth(),
273
+ date.getUTCDate()
274
+ );
275
+ const startMs = Date.UTC(
276
+ monthStart.getUTCFullYear(),
277
+ monthStart.getUTCMonth(),
278
+ monthStart.getUTCDate()
279
+ );
280
+ return Math.round((dateMs - startMs) / (1e3 * 60 * 60 * 24));
281
+ };
282
+ var isToday = (date) => {
283
+ const now = /* @__PURE__ */ new Date();
284
+ const today = new Date(Date.UTC(
285
+ now.getFullYear(),
286
+ now.getMonth(),
287
+ now.getDate()
288
+ ));
289
+ const compareDate = new Date(Date.UTC(
290
+ date.getUTCFullYear(),
291
+ date.getUTCMonth(),
292
+ date.getUTCDate()
293
+ ));
294
+ return today.getTime() === compareDate.getTime();
295
+ };
296
+ var isWeekend = (date) => {
297
+ const day = date.getUTCDay();
298
+ return day === 0 || day === 6;
299
+ };
300
+ var createDateKey = (date) => {
301
+ return `${date.getUTCFullYear()}-${date.getUTCMonth()}-${date.getUTCDate()}`;
302
+ };
303
+ var createCustomDayPredicate = (config) => {
304
+ const { customDays, isWeekend: basePredicate } = config;
305
+ const workdaySet = /* @__PURE__ */ new Set();
306
+ const weekendSet = /* @__PURE__ */ new Set();
307
+ if (customDays && customDays.length > 0) {
308
+ for (const item of customDays) {
309
+ const key = createDateKey(item.date);
310
+ if (item.type === "workday") {
311
+ workdaySet.add(key);
312
+ } else {
313
+ weekendSet.add(key);
314
+ }
315
+ }
316
+ }
317
+ return (date) => {
318
+ const key = createDateKey(date);
319
+ if (workdaySet.has(key)) {
320
+ return false;
321
+ }
322
+ if (weekendSet.has(key)) {
323
+ return true;
324
+ }
325
+ if (basePredicate) {
326
+ return basePredicate(date);
327
+ }
328
+ const dayOfWeek = date.getUTCDay();
329
+ return dayOfWeek === 0 || dayOfWeek === 6;
330
+ };
331
+ };
332
+ var getMultiMonthDays = (tasks) => {
333
+ if (!tasks || tasks.length === 0) {
334
+ return getMonthDays(/* @__PURE__ */ new Date());
335
+ }
336
+ let minDate = null;
337
+ let maxDate = null;
338
+ for (const task of tasks) {
339
+ const start = parseUTCDate(task.startDate);
340
+ const end = parseUTCDate(task.endDate);
341
+ if (!minDate || start.getTime() < minDate.getTime()) {
342
+ minDate = start;
343
+ }
344
+ if (!maxDate || end.getTime() > maxDate.getTime()) {
345
+ maxDate = end;
346
+ }
347
+ }
348
+ if (!minDate || !maxDate) {
349
+ return getMonthDays(/* @__PURE__ */ new Date());
350
+ }
351
+ const startOfMonth2 = new Date(Date.UTC(
352
+ minDate.getUTCFullYear(),
353
+ minDate.getUTCMonth(),
354
+ 1
355
+ ));
356
+ const endOfMonth = new Date(Date.UTC(
357
+ maxDate.getUTCFullYear(),
358
+ maxDate.getUTCMonth() + 1 + 2,
359
+ // Original + 2 months padding after
360
+ 0
361
+ ));
362
+ const days = [];
363
+ const current = new Date(startOfMonth2);
364
+ while (current.getTime() <= endOfMonth.getTime()) {
365
+ days.push(new Date(Date.UTC(
366
+ current.getUTCFullYear(),
367
+ current.getUTCMonth(),
368
+ current.getUTCDate()
369
+ )));
370
+ current.setUTCDate(current.getUTCDate() + 1);
371
+ }
372
+ return days;
373
+ };
374
+ var getMonthSpans = (dateRange) => {
375
+ if (dateRange.length === 0) {
376
+ return [];
377
+ }
378
+ const spans = [];
379
+ let currentMonthYear = `${dateRange[0].getUTCFullYear()}-${dateRange[0].getUTCMonth()}`;
380
+ let startOfMonthIndex = 0;
381
+ for (let i = 0; i < dateRange.length; i++) {
382
+ const date = dateRange[i];
383
+ const monthYear = `${date.getUTCFullYear()}-${date.getUTCMonth()}`;
384
+ if (monthYear !== currentMonthYear) {
385
+ spans.push({
386
+ month: new Date(Date.UTC(
387
+ dateRange[startOfMonthIndex].getUTCFullYear(),
388
+ dateRange[startOfMonthIndex].getUTCMonth(),
389
+ 1
390
+ )),
391
+ days: i - startOfMonthIndex,
392
+ startIndex: startOfMonthIndex
393
+ });
394
+ currentMonthYear = monthYear;
395
+ startOfMonthIndex = i;
396
+ }
397
+ if (i === dateRange.length - 1) {
398
+ spans.push({
399
+ month: new Date(Date.UTC(
400
+ date.getUTCFullYear(),
401
+ date.getUTCMonth(),
402
+ 1
403
+ )),
404
+ days: i - startOfMonthIndex + 1,
405
+ startIndex: startOfMonthIndex
406
+ });
407
+ }
408
+ }
409
+ return spans;
410
+ };
411
+ var formatDateLabel = (date) => {
412
+ const parsed = parseUTCDate(date);
413
+ const day = String(parsed.getUTCDate()).padStart(2, "0");
414
+ const month = String(parsed.getUTCMonth() + 1).padStart(2, "0");
415
+ return `${day}.${month}`;
416
+ };
417
+ var MONTH_ABBR = [
418
+ "\u044F\u043D\u0432",
419
+ "\u0444\u0435\u0432",
420
+ "\u043C\u0430\u0440",
421
+ "\u0430\u043F\u0440",
422
+ "\u043C\u0430\u044F",
423
+ "\u0438\u044E\u043D",
424
+ "\u0438\u044E\u043B",
425
+ "\u0430\u0432\u0433",
426
+ "\u0441\u0435\u043D",
427
+ "\u043E\u043A\u0442",
428
+ "\u043D\u043E\u044F",
429
+ "\u0434\u0435\u043A"
430
+ ];
431
+ var formatDateRangeLabel = (startDate, endDate) => {
432
+ const start = parseUTCDate(startDate);
433
+ const end = parseUTCDate(endDate);
434
+ const startDay = start.getUTCDate();
435
+ const endDay = end.getUTCDate();
436
+ const startMonth = start.getUTCMonth();
437
+ const endMonth = end.getUTCMonth();
438
+ const startYear = start.getUTCFullYear();
439
+ const endYear = end.getUTCFullYear();
440
+ if (startMonth === endMonth && startYear === endYear) {
441
+ if (startDay === endDay) {
442
+ return `${startDay} ${MONTH_ABBR[startMonth]}`;
443
+ }
444
+ return `${startDay}\u2013${endDay} ${MONTH_ABBR[startMonth]}`;
445
+ }
446
+ if (startYear === endYear) {
447
+ return `${startDay} ${MONTH_ABBR[startMonth]}\u2013${endDay} ${MONTH_ABBR[endMonth]}`;
448
+ }
449
+ return `${startDay} ${MONTH_ABBR[startMonth]} ${startYear}\u2013${endDay} ${MONTH_ABBR[endMonth]} ${endYear}`;
450
+ };
451
+ var getWeekBlocks = (days) => {
452
+ if (days.length === 0) return [];
453
+ const blocks = [];
454
+ let blockStart = 0;
455
+ while (blockStart < days.length) {
456
+ const maxBlockEnd = Math.min(blockStart + 7, days.length);
457
+ const startMonthYear = `${days[blockStart].getUTCFullYear()}-${days[blockStart].getUTCMonth()}`;
458
+ let actualBlockEnd = blockStart + 7;
459
+ if (actualBlockEnd > days.length) {
460
+ actualBlockEnd = days.length;
461
+ }
462
+ for (let i = blockStart + 1; i < maxBlockEnd; i++) {
463
+ const monthYear = `${days[i].getUTCFullYear()}-${days[i].getUTCMonth()}`;
464
+ if (monthYear !== startMonthYear) {
465
+ actualBlockEnd = i;
466
+ break;
467
+ }
468
+ }
469
+ blocks.push({
470
+ startDate: days[blockStart],
471
+ days: actualBlockEnd - blockStart
472
+ });
473
+ blockStart = actualBlockEnd;
474
+ }
475
+ return blocks;
476
+ };
477
+ var getWeekSpans = (days) => {
478
+ const blocks = getWeekBlocks(days);
479
+ if (blocks.length === 0) return [];
480
+ const spans = [];
481
+ let currentMonthYear = `${blocks[0].startDate.getUTCFullYear()}-${blocks[0].startDate.getUTCMonth()}`;
482
+ let startIndex = 0;
483
+ let totalDays = 0;
484
+ for (let i = 0; i < blocks.length; i++) {
485
+ const block = blocks[i];
486
+ const monthYear = `${block.startDate.getUTCFullYear()}-${block.startDate.getUTCMonth()}`;
487
+ if (monthYear !== currentMonthYear) {
488
+ spans.push({
489
+ month: new Date(Date.UTC(
490
+ blocks[startIndex].startDate.getUTCFullYear(),
491
+ blocks[startIndex].startDate.getUTCMonth(),
492
+ 1
493
+ )),
494
+ days: totalDays,
495
+ startIndex
496
+ });
497
+ currentMonthYear = monthYear;
498
+ startIndex = i;
499
+ totalDays = 0;
500
+ }
501
+ totalDays += block.days;
502
+ if (i === blocks.length - 1) {
503
+ spans.push({
504
+ month: new Date(Date.UTC(
505
+ block.startDate.getUTCFullYear(),
506
+ block.startDate.getUTCMonth(),
507
+ 1
508
+ )),
509
+ days: totalDays,
510
+ startIndex
511
+ });
512
+ }
513
+ }
514
+ return spans;
515
+ };
516
+ var getMonthBlocks = (days) => {
517
+ if (days.length === 0) return [];
518
+ return getMonthSpans(days).map((span) => ({
519
+ startDate: span.month,
520
+ days: span.days
521
+ }));
522
+ };
523
+ var getYearSpans = (days) => {
524
+ const blocks = getMonthBlocks(days);
525
+ if (blocks.length === 0) return [];
526
+ const spans = [];
527
+ let currentYear = blocks[0].startDate.getUTCFullYear();
528
+ let startIndex = 0;
529
+ let totalDays = 0;
530
+ for (let i = 0; i < blocks.length; i++) {
531
+ const blockYear = blocks[i].startDate.getUTCFullYear();
532
+ if (blockYear !== currentYear) {
533
+ spans.push({
534
+ year: new Date(Date.UTC(currentYear, 0, 1)),
535
+ days: totalDays,
536
+ startIndex
537
+ });
538
+ currentYear = blockYear;
539
+ startIndex = i;
540
+ totalDays = 0;
541
+ }
542
+ totalDays += blocks[i].days;
543
+ if (i === blocks.length - 1) {
544
+ spans.push({
545
+ year: new Date(Date.UTC(currentYear, 0, 1)),
546
+ days: totalDays,
547
+ startIndex
548
+ });
549
+ }
550
+ }
551
+ return spans;
552
+ };
553
+ var normalizeTaskDates = (startDate, endDate) => {
554
+ const start = parseUTCDate(startDate);
555
+ const end = parseUTCDate(endDate);
556
+ if (end.getTime() < start.getTime()) {
557
+ return {
558
+ startDate: end.toISOString().split("T")[0],
559
+ endDate: start.toISOString().split("T")[0]
560
+ };
561
+ }
562
+ return {
563
+ startDate: start.toISOString().split("T")[0],
564
+ endDate: end.toISOString().split("T")[0]
565
+ };
566
+ };
567
+ function getBusinessDaysCount2(startDate, endDate, weekendPredicate) {
568
+ return getBusinessDaysCount(startDate, endDate, weekendPredicate);
569
+ }
570
+ function addBusinessDays2(startDate, businessDays, weekendPredicate) {
571
+ const result = addBusinessDays(startDate, businessDays, weekendPredicate);
572
+ return result.toISOString().split("T")[0];
573
+ }
574
+ function subtractBusinessDays2(endDate, businessDays, weekendPredicate) {
575
+ const result = subtractBusinessDays(endDate, businessDays, weekendPredicate);
576
+ return result.toISOString().split("T")[0];
577
+ }
620
578
 
621
579
  // src/core/scheduling/dependencies.ts
622
- init_dateMath();
623
580
  function normalizePredecessorDates(predecessor, parseDateFn) {
624
581
  const predStart = parseDateFn(predecessor.startDate);
625
582
  const isMilestone = predecessor.type === "milestone";
@@ -726,9 +683,6 @@ function calculateSuccessorDate(predecessorStart, predecessorEnd, linkType, lag
726
683
  return shiftBusinessDayOffset(anchorDate, offset, weekendPredicate);
727
684
  }
728
685
 
729
- // src/core/scheduling/cascade.ts
730
- init_dateMath();
731
-
732
686
  // src/core/scheduling/hierarchy.ts
733
687
  function getChildren(parentId, tasks) {
734
688
  return tasks.filter((t) => t.parentId === parentId);
@@ -850,7 +804,6 @@ function areTasksHierarchicallyRelated(taskId1, taskId2, tasks) {
850
804
  }
851
805
 
852
806
  // src/core/scheduling/commands.ts
853
- init_dateMath();
854
807
  function buildTaskRangeFromStart(startDate, duration, businessDays = false, weekendPredicate, snapDirection = 1) {
855
808
  const normalizedStart = businessDays && weekendPredicate ? alignToWorkingDay(startDate, snapDirection, weekendPredicate) : normalizeUTCDate(startDate);
856
809
  if (businessDays && weekendPredicate) {
@@ -1258,11 +1211,7 @@ function universalCascade(movedTask, newStart, newEnd, allTasks, businessDays =
1258
1211
  return Array.from(resultMap.values());
1259
1212
  }
1260
1213
 
1261
- // src/core/scheduling/modeSwitch.ts
1262
- init_dateMath();
1263
-
1264
1214
  // src/core/scheduling/execute.ts
1265
- init_dateMath();
1266
1215
  function toIsoDate(date) {
1267
1216
  return date.toISOString().split("T")[0];
1268
1217
  }
@@ -1704,7 +1653,6 @@ function validateDependencies(tasks) {
1704
1653
  }
1705
1654
 
1706
1655
  // src/utils/hierarchyOrder.ts
1707
- init_dateUtils();
1708
1656
  function flattenHierarchy(tasks) {
1709
1657
  const byId = new Map(tasks.map((task) => [task.id, task]));
1710
1658
  const byParent = /* @__PURE__ */ new Map();
@@ -1760,7 +1708,6 @@ function normalizeHierarchyTasks(tasks) {
1760
1708
  var import_react = require("react");
1761
1709
  var import_date_fns = require("date-fns");
1762
1710
  var import_locale = require("date-fns/locale");
1763
- init_dateUtils();
1764
1711
  var import_jsx_runtime = require("react/jsx-runtime");
1765
1712
  var TimeScaleHeader = ({
1766
1713
  days,
@@ -1949,7 +1896,6 @@ var TimeScaleHeader_default = TimeScaleHeader;
1949
1896
 
1950
1897
  // src/components/TaskRow/TaskRow.tsx
1951
1898
  var import_react3 = __toESM(require("react"));
1952
- init_dateUtils();
1953
1899
 
1954
1900
  // src/utils/geometry.ts
1955
1901
  var getUTCDayDifference = (date1, date2) => {
@@ -2160,8 +2106,7 @@ var calculateDependencyPath = (from, to, arrivesFromRight) => {
2160
2106
  }
2161
2107
  };
2162
2108
  var calculateWeekGridLines = (dateRange, dayWidth) => {
2163
- const { getWeekBlocks: getWeekBlocks2 } = (init_dateUtils(), __toCommonJS(dateUtils_exports));
2164
- const blocks = getWeekBlocks2(dateRange);
2109
+ const blocks = getWeekBlocks(dateRange);
2165
2110
  const lines = [];
2166
2111
  let currentDayIndex = 0;
2167
2112
  for (let i = 0; i < blocks.length; i++) {
@@ -2217,7 +2162,6 @@ var calculateOrthogonalPath = (from, to) => {
2217
2162
  };
2218
2163
 
2219
2164
  // src/utils/expired.ts
2220
- init_dateUtils();
2221
2165
  var isTaskExpired = (task, referenceDate = /* @__PURE__ */ new Date()) => {
2222
2166
  if (!task) return false;
2223
2167
  const actualProgress = task.progress ?? 0;
@@ -2238,7 +2182,6 @@ var isTaskExpired = (task, referenceDate = /* @__PURE__ */ new Date()) => {
2238
2182
  };
2239
2183
 
2240
2184
  // src/utils/taskType.ts
2241
- init_dateUtils();
2242
2185
  var TASK_TYPE_DEFAULT = "task";
2243
2186
  function getTaskType(task) {
2244
2187
  return task.type ?? TASK_TYPE_DEFAULT;
@@ -2272,7 +2215,6 @@ function normalizeTaskDatesForType(task) {
2272
2215
  var import_react2 = require("react");
2273
2216
 
2274
2217
  // src/adapters/scheduling/drag.ts
2275
- init_dateMath();
2276
2218
  function resolveDateRangeFromPixels(mode, left, width, monthStart, dayWidth, task, businessDays, weekendPredicate) {
2277
2219
  const dayOffset = Math.round(left / dayWidth);
2278
2220
  const rawStartDate = new Date(Date.UTC(
@@ -3157,7 +3099,6 @@ var TaskRow_default = TaskRow;
3157
3099
 
3158
3100
  // src/components/TodayIndicator/TodayIndicator.tsx
3159
3101
  var import_react4 = require("react");
3160
- init_dateUtils();
3161
3102
  var import_jsx_runtime3 = require("react/jsx-runtime");
3162
3103
  var TodayIndicator = ({ monthStart, dayWidth }) => {
3163
3104
  const today = /* @__PURE__ */ new Date();
@@ -3593,7 +3534,6 @@ var DependencyLines_default = DependencyLines;
3593
3534
 
3594
3535
  // src/components/TaskList/TaskList.tsx
3595
3536
  var import_react12 = __toESM(require("react"));
3596
- init_dateUtils();
3597
3537
 
3598
3538
  // src/utils/taskListReorder.ts
3599
3539
  function getDescendantIds(taskId, tasks) {
@@ -3682,7 +3622,6 @@ var PopoverContent = ({
3682
3622
 
3683
3623
  // src/components/TaskList/TaskListRow.tsx
3684
3624
  var import_react10 = __toESM(require("react"));
3685
- init_dateUtils();
3686
3625
 
3687
3626
  // src/components/ui/Input.tsx
3688
3627
  var import_react7 = __toESM(require("react"));
@@ -4186,7 +4125,6 @@ var LINK_TYPE_LABELS = {
4186
4125
  };
4187
4126
 
4188
4127
  // src/components/TaskList/defaultTaskDates.ts
4189
- init_dateUtils();
4190
4128
  var DAY_MS2 = 24 * 60 * 60 * 1e3;
4191
4129
  var DEFAULT_TASK_DURATION_DAYS = 5;
4192
4130
  function toISODate(date) {
@@ -7383,10 +7321,8 @@ var TaskList = ({
7383
7321
 
7384
7322
  // src/components/ResourceTimelineChart/ResourceTimelineChart.tsx
7385
7323
  var import_react14 = require("react");
7386
- init_dateUtils();
7387
7324
 
7388
7325
  // src/utils/resourceTimelineLayout.ts
7389
- init_dateUtils();
7390
7326
  var isInvalidDate = (date) => Number.isNaN(date.getTime());
7391
7327
  var getUTCDayNumber = (date) => {
7392
7328
  return Math.floor(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()) / 864e5);
@@ -7781,35 +7717,6 @@ var ITEM_OUTER_VERTICAL_INSET = 2;
7781
7717
  var ITEM_INNER_VERTICAL_INSET = 1;
7782
7718
  var ITEM_HORIZONTAL_INSET = 1;
7783
7719
  var isValidDate = (date) => !Number.isNaN(date.getTime());
7784
- var getResourceTimelineDays = (items) => {
7785
- if (items.length === 0) {
7786
- return getMonthDays(/* @__PURE__ */ new Date());
7787
- }
7788
- let minDate = null;
7789
- let maxDate = null;
7790
- for (const item of items) {
7791
- const startDate = parseUTCDate(item.startDate);
7792
- const endDate = parseUTCDate(item.endDate);
7793
- if (!minDate || startDate.getTime() < minDate.getTime()) {
7794
- minDate = startDate;
7795
- }
7796
- if (!maxDate || endDate.getTime() > maxDate.getTime()) {
7797
- maxDate = endDate;
7798
- }
7799
- }
7800
- if (!minDate || !maxDate) {
7801
- return getMonthDays(/* @__PURE__ */ new Date());
7802
- }
7803
- const startOfMonth2 = new Date(Date.UTC(minDate.getUTCFullYear(), minDate.getUTCMonth(), 1));
7804
- const endOfMonth = new Date(Date.UTC(maxDate.getUTCFullYear(), maxDate.getUTCMonth() + 1, 0));
7805
- const days = [];
7806
- const current = new Date(startOfMonth2);
7807
- while (current.getTime() <= endOfMonth.getTime()) {
7808
- days.push(new Date(Date.UTC(current.getUTCFullYear(), current.getUTCMonth(), current.getUTCDate())));
7809
- current.setUTCDate(current.getUTCDate() + 1);
7810
- }
7811
- return days;
7812
- };
7813
7720
  var collectValidItems = (resources) => {
7814
7721
  return resources.flatMap(
7815
7722
  (resource) => resource.items.flatMap((item) => {
@@ -7882,9 +7789,12 @@ var getDurationValue = (startDate, endDate, businessDays, weekendPredicate) => b
7882
7789
  function ResourceTimelineChart({
7883
7790
  resources,
7884
7791
  dayWidth = DEFAULT_DAY_WIDTH,
7792
+ viewMode = "day",
7885
7793
  rowHeaderWidth = DEFAULT_ROW_HEADER_WIDTH,
7886
7794
  laneHeight = DEFAULT_LANE_HEIGHT,
7887
7795
  headerHeight = DEFAULT_HEADER_HEIGHT,
7796
+ containerHeight,
7797
+ allowVerticalPan = false,
7888
7798
  customDays,
7889
7799
  isWeekend: isWeekend3,
7890
7800
  businessDays = true,
@@ -7892,15 +7802,14 @@ function ResourceTimelineChart({
7892
7802
  disableResourceReassignment,
7893
7803
  renderItem,
7894
7804
  getItemClassName,
7805
+ onResourceItemClick,
7895
7806
  onResourceItemMove
7896
7807
  }) {
7897
7808
  const scrollContainerRef = (0, import_react14.useRef)(null);
7898
7809
  const gridRef = (0, import_react14.useRef)(null);
7899
7810
  const panStateRef = (0, import_react14.useRef)(null);
7900
7811
  const validItems = (0, import_react14.useMemo)(() => collectValidItems(resources), [resources]);
7901
- const dateRange = (0, import_react14.useMemo)(() => {
7902
- return getResourceTimelineDays(validItems);
7903
- }, [validItems]);
7812
+ const dateRange = (0, import_react14.useMemo)(() => getMultiMonthDays(validItems), [validItems]);
7904
7813
  const monthStart = (0, import_react14.useMemo)(() => {
7905
7814
  const firstDay = dateRange[0] ?? /* @__PURE__ */ new Date();
7906
7815
  return new Date(Date.UTC(firstDay.getUTCFullYear(), firstDay.getUTCMonth(), 1));
@@ -7980,7 +7889,9 @@ function ResourceTimelineChart({
7980
7889
  return;
7981
7890
  }
7982
7891
  container.scrollLeft = pan.scrollX - (event.clientX - pan.startX);
7983
- container.scrollTop = pan.scrollY - (event.clientY - pan.startY);
7892
+ if (allowVerticalPan) {
7893
+ container.scrollTop = pan.scrollY - (event.clientY - pan.startY);
7894
+ }
7984
7895
  };
7985
7896
  const handlePanEnd = () => {
7986
7897
  if (!panStateRef.current?.active) {
@@ -7998,13 +7909,18 @@ function ResourceTimelineChart({
7998
7909
  window.removeEventListener("mousemove", handlePanMove);
7999
7910
  window.removeEventListener("mouseup", handlePanEnd);
8000
7911
  };
8001
- }, []);
7912
+ }, [allowVerticalPan]);
8002
7913
  return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "gantt-container gantt-resourceTimeline", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
8003
7914
  "div",
8004
7915
  {
8005
7916
  ref: scrollContainerRef,
8006
7917
  className: "gantt-resourceTimeline-scrollContainer",
8007
- style: { cursor: "grab" },
7918
+ style: {
7919
+ cursor: "grab",
7920
+ height: containerHeight ?? "auto",
7921
+ overflowY: containerHeight === void 0 ? void 0 : "auto"
7922
+ },
7923
+ "data-allow-vertical-pan": allowVerticalPan ? "true" : "false",
8008
7924
  onMouseDown: handlePanStart,
8009
7925
  children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "gantt-resourceTimeline-scrollContent", children: [
8010
7926
  /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
@@ -8058,6 +7974,7 @@ function ResourceTimelineChart({
8058
7974
  days: dateRange,
8059
7975
  dayWidth,
8060
7976
  headerHeight,
7977
+ viewMode,
8061
7978
  isCustomWeekend: weekendPredicate
8062
7979
  }
8063
7980
  ) }),
@@ -8074,6 +7991,7 @@ function ResourceTimelineChart({
8074
7991
  dateRange,
8075
7992
  dayWidth,
8076
7993
  totalHeight: layout.totalHeight,
7994
+ viewMode,
8077
7995
  isCustomWeekend: weekendPredicate
8078
7996
  }
8079
7997
  ),
@@ -8139,6 +8057,18 @@ function ResourceTimelineChart({
8139
8057
  className,
8140
8058
  "data-resource-item-id": layoutItem.itemId,
8141
8059
  onMouseDown: (event) => startDrag(event, layoutItem),
8060
+ onClick: () => onResourceItemClick?.(layoutItem.item),
8061
+ onKeyDown: (event) => {
8062
+ if (!onResourceItemClick) {
8063
+ return;
8064
+ }
8065
+ if (event.key === "Enter" || event.key === " ") {
8066
+ event.preventDefault();
8067
+ onResourceItemClick(layoutItem.item);
8068
+ }
8069
+ },
8070
+ role: onResourceItemClick ? "button" : void 0,
8071
+ tabIndex: onResourceItemClick ? 0 : void 0,
8142
8072
  style: {
8143
8073
  left: `${itemGeometry.left}px`,
8144
8074
  top: `${itemGeometry.top}px`,
@@ -8176,18 +8106,19 @@ function ResourceTimelineChart({
8176
8106
  },
8177
8107
  `conflict-overlay-${index}`
8178
8108
  )),
8179
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "gantt-resourceTimeline-itemInner", children: renderItem ? renderItem(layoutItem.item, renderContext) : /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
8180
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
8181
- "span",
8182
- {
8183
- className: "gantt-resourceTimeline-itemDurationChip",
8184
- "aria-label": `${durationValue} \u0434`,
8185
- children: durationValue
8186
- }
8187
- ),
8188
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "gantt-resourceTimeline-itemTitle", children: layoutItem.item.title }),
8189
- layoutItem.item.subtitle && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "gantt-resourceTimeline-itemSubtitle", children: layoutItem.item.subtitle }),
8190
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "gantt-resourceTimeline-itemDates", children: formatDateRangeLabel(layoutItem.startDate, layoutItem.endDate) })
8109
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "gantt-resourceTimeline-itemInner", children: renderItem ? renderItem(layoutItem.item, renderContext) : /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "gantt-resourceTimeline-defaultItemContent", children: [
8110
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "gantt-resourceTimeline-defaultItemMain", children: [
8111
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
8112
+ "span",
8113
+ {
8114
+ className: "gantt-resourceTimeline-itemDurationChip",
8115
+ "aria-label": `${durationValue} \u0434`,
8116
+ children: durationValue
8117
+ }
8118
+ ),
8119
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "gantt-resourceTimeline-itemTitle", children: layoutItem.item.title })
8120
+ ] }),
8121
+ layoutItem.item.subtitle && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "gantt-resourceTimeline-itemSubtitle", children: layoutItem.item.subtitle })
8191
8122
  ] }) })
8192
8123
  ]
8193
8124
  },
@@ -9257,11 +9188,7 @@ var Button = import_react16.default.forwardRef(
9257
9188
  );
9258
9189
  Button.displayName = "Button";
9259
9190
 
9260
- // src/utils/index.ts
9261
- init_dateUtils();
9262
-
9263
9191
  // src/filters/index.ts
9264
- init_dateUtils();
9265
9192
  var and = (...predicates) => (task) => predicates.every((p) => p(task));
9266
9193
  var or = (...predicates) => (task) => predicates.some((p) => p(task));
9267
9194
  var not = (predicate) => (task) => !predicate(task);