gantt-lib 0.77.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/core/scheduling/index.d.mts +1 -1
- package/dist/core/scheduling/index.d.ts +1 -1
- package/dist/{index-BUAal8CL.d.mts → index-CZzZrxn-.d.mts} +2 -0
- package/dist/{index-BUAal8CL.d.ts → index-CZzZrxn-.d.ts} +2 -0
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +443 -534
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +335 -443
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +1 -0
- package/package.json +1 -1
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/
|
|
619
|
-
|
|
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
|
|
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,11 @@ 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,
|
|
7888
7797
|
allowVerticalPan = false,
|
|
7889
7798
|
customDays,
|
|
7890
7799
|
isWeekend: isWeekend3,
|
|
@@ -7900,9 +7809,7 @@ function ResourceTimelineChart({
|
|
|
7900
7809
|
const gridRef = (0, import_react14.useRef)(null);
|
|
7901
7810
|
const panStateRef = (0, import_react14.useRef)(null);
|
|
7902
7811
|
const validItems = (0, import_react14.useMemo)(() => collectValidItems(resources), [resources]);
|
|
7903
|
-
const dateRange = (0, import_react14.useMemo)(() =>
|
|
7904
|
-
return getResourceTimelineDays(validItems);
|
|
7905
|
-
}, [validItems]);
|
|
7812
|
+
const dateRange = (0, import_react14.useMemo)(() => getMultiMonthDays(validItems), [validItems]);
|
|
7906
7813
|
const monthStart = (0, import_react14.useMemo)(() => {
|
|
7907
7814
|
const firstDay = dateRange[0] ?? /* @__PURE__ */ new Date();
|
|
7908
7815
|
return new Date(Date.UTC(firstDay.getUTCFullYear(), firstDay.getUTCMonth(), 1));
|
|
@@ -8008,7 +7915,11 @@ function ResourceTimelineChart({
|
|
|
8008
7915
|
{
|
|
8009
7916
|
ref: scrollContainerRef,
|
|
8010
7917
|
className: "gantt-resourceTimeline-scrollContainer",
|
|
8011
|
-
style: {
|
|
7918
|
+
style: {
|
|
7919
|
+
cursor: "grab",
|
|
7920
|
+
height: containerHeight ?? "auto",
|
|
7921
|
+
overflowY: containerHeight === void 0 ? void 0 : "auto"
|
|
7922
|
+
},
|
|
8012
7923
|
"data-allow-vertical-pan": allowVerticalPan ? "true" : "false",
|
|
8013
7924
|
onMouseDown: handlePanStart,
|
|
8014
7925
|
children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "gantt-resourceTimeline-scrollContent", children: [
|
|
@@ -8063,6 +7974,7 @@ function ResourceTimelineChart({
|
|
|
8063
7974
|
days: dateRange,
|
|
8064
7975
|
dayWidth,
|
|
8065
7976
|
headerHeight,
|
|
7977
|
+
viewMode,
|
|
8066
7978
|
isCustomWeekend: weekendPredicate
|
|
8067
7979
|
}
|
|
8068
7980
|
) }),
|
|
@@ -8079,6 +7991,7 @@ function ResourceTimelineChart({
|
|
|
8079
7991
|
dateRange,
|
|
8080
7992
|
dayWidth,
|
|
8081
7993
|
totalHeight: layout.totalHeight,
|
|
7994
|
+
viewMode,
|
|
8082
7995
|
isCustomWeekend: weekendPredicate
|
|
8083
7996
|
}
|
|
8084
7997
|
),
|
|
@@ -9275,11 +9188,7 @@ var Button = import_react16.default.forwardRef(
|
|
|
9275
9188
|
);
|
|
9276
9189
|
Button.displayName = "Button";
|
|
9277
9190
|
|
|
9278
|
-
// src/utils/index.ts
|
|
9279
|
-
init_dateUtils();
|
|
9280
|
-
|
|
9281
9191
|
// src/filters/index.ts
|
|
9282
|
-
init_dateUtils();
|
|
9283
9192
|
var and = (...predicates) => (task) => predicates.every((p) => p(task));
|
|
9284
9193
|
var or = (...predicates) => (task) => predicates.some((p) => p(task));
|
|
9285
9194
|
var not = (predicate) => (task) => !predicate(task);
|