gantt-lib 0.75.1 → 0.77.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-B2Hmdkey.d.mts → index-BUAal8CL.d.mts} +17 -1
- package/dist/{index-B2Hmdkey.d.ts → index-BUAal8CL.d.ts} +17 -1
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +13 -4
- package/dist/index.d.ts +13 -4
- package/dist/index.js +362 -35
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +362 -35
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +110 -16
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -7305,12 +7305,86 @@ var compareParsedItems = (a, b) => {
|
|
|
7305
7305
|
}
|
|
7306
7306
|
return a.item.id.localeCompare(b.item.id);
|
|
7307
7307
|
};
|
|
7308
|
+
var getOverlapRange = (left, right) => {
|
|
7309
|
+
const startDay = Math.max(getUTCDayNumber(left.startDate), getUTCDayNumber(right.startDate));
|
|
7310
|
+
const endDay = Math.min(getUTCDayNumber(left.endDate), getUTCDayNumber(right.endDate));
|
|
7311
|
+
if (startDay > endDay) {
|
|
7312
|
+
return null;
|
|
7313
|
+
}
|
|
7314
|
+
return {
|
|
7315
|
+
startDate: new Date(startDay * 864e5),
|
|
7316
|
+
endDate: new Date(endDay * 864e5),
|
|
7317
|
+
itemIds: [left.item.id, right.item.id]
|
|
7318
|
+
};
|
|
7319
|
+
};
|
|
7320
|
+
var mergeConflictRanges = (ranges) => {
|
|
7321
|
+
const sortedRanges = [...ranges].sort(
|
|
7322
|
+
(left, right) => getUTCDayNumber(left.startDate) - getUTCDayNumber(right.startDate) || getUTCDayNumber(left.endDate) - getUTCDayNumber(right.endDate)
|
|
7323
|
+
);
|
|
7324
|
+
const merged = [];
|
|
7325
|
+
for (const range of sortedRanges) {
|
|
7326
|
+
const previous = merged[merged.length - 1];
|
|
7327
|
+
const rangeStartDay = getUTCDayNumber(range.startDate);
|
|
7328
|
+
const rangeEndDay = getUTCDayNumber(range.endDate);
|
|
7329
|
+
if (!previous || rangeStartDay > getUTCDayNumber(previous.endDate) + 1) {
|
|
7330
|
+
merged.push({
|
|
7331
|
+
startDate: range.startDate,
|
|
7332
|
+
endDate: range.endDate,
|
|
7333
|
+
itemIds: [...range.itemIds]
|
|
7334
|
+
});
|
|
7335
|
+
continue;
|
|
7336
|
+
}
|
|
7337
|
+
if (rangeEndDay > getUTCDayNumber(previous.endDate)) {
|
|
7338
|
+
previous.endDate = range.endDate;
|
|
7339
|
+
}
|
|
7340
|
+
previous.itemIds = Array.from(/* @__PURE__ */ new Set([...previous.itemIds, ...range.itemIds])).sort();
|
|
7341
|
+
}
|
|
7342
|
+
return merged;
|
|
7343
|
+
};
|
|
7344
|
+
var calculateConflictInfo = (parsedItems) => {
|
|
7345
|
+
const conflictRangesByItemId = /* @__PURE__ */ new Map();
|
|
7346
|
+
const conflictsWithByItemId = /* @__PURE__ */ new Map();
|
|
7347
|
+
for (let i = 0; i < parsedItems.length; i++) {
|
|
7348
|
+
for (let j = i + 1; j < parsedItems.length; j++) {
|
|
7349
|
+
const left = parsedItems[i];
|
|
7350
|
+
const right = parsedItems[j];
|
|
7351
|
+
if (getUTCDayNumber(right.startDate) > getUTCDayNumber(left.endDate)) {
|
|
7352
|
+
break;
|
|
7353
|
+
}
|
|
7354
|
+
const overlap = getOverlapRange(left, right);
|
|
7355
|
+
if (!overlap) {
|
|
7356
|
+
continue;
|
|
7357
|
+
}
|
|
7358
|
+
const leftRanges = conflictRangesByItemId.get(left.item.id) ?? [];
|
|
7359
|
+
const rightRanges = conflictRangesByItemId.get(right.item.id) ?? [];
|
|
7360
|
+
leftRanges.push(overlap);
|
|
7361
|
+
rightRanges.push(overlap);
|
|
7362
|
+
conflictRangesByItemId.set(left.item.id, leftRanges);
|
|
7363
|
+
conflictRangesByItemId.set(right.item.id, rightRanges);
|
|
7364
|
+
const leftConflicts = conflictsWithByItemId.get(left.item.id) ?? /* @__PURE__ */ new Set();
|
|
7365
|
+
const rightConflicts = conflictsWithByItemId.get(right.item.id) ?? /* @__PURE__ */ new Set();
|
|
7366
|
+
leftConflicts.add(right.item.id);
|
|
7367
|
+
rightConflicts.add(left.item.id);
|
|
7368
|
+
conflictsWithByItemId.set(left.item.id, leftConflicts);
|
|
7369
|
+
conflictsWithByItemId.set(right.item.id, rightConflicts);
|
|
7370
|
+
}
|
|
7371
|
+
}
|
|
7372
|
+
const result = /* @__PURE__ */ new Map();
|
|
7373
|
+
for (const parsedItem of parsedItems) {
|
|
7374
|
+
result.set(parsedItem.item.id, {
|
|
7375
|
+
conflictRanges: mergeConflictRanges(conflictRangesByItemId.get(parsedItem.item.id) ?? []),
|
|
7376
|
+
conflictsWith: Array.from(conflictsWithByItemId.get(parsedItem.item.id) ?? []).sort()
|
|
7377
|
+
});
|
|
7378
|
+
}
|
|
7379
|
+
return result;
|
|
7380
|
+
};
|
|
7308
7381
|
var layoutResourceTimelineItems = (resources, options) => {
|
|
7309
7382
|
const rows = [];
|
|
7310
7383
|
const items = [];
|
|
7311
7384
|
const diagnostics = [];
|
|
7312
7385
|
let currentTop = 0;
|
|
7313
|
-
|
|
7386
|
+
const rowGap = options.rowGap ?? 0;
|
|
7387
|
+
resources.forEach((resource, resourceIndex) => {
|
|
7314
7388
|
const parsedItems = [];
|
|
7315
7389
|
for (const item of resource.items) {
|
|
7316
7390
|
try {
|
|
@@ -7329,6 +7403,7 @@ var layoutResourceTimelineItems = (resources, options) => {
|
|
|
7329
7403
|
}
|
|
7330
7404
|
}
|
|
7331
7405
|
parsedItems.sort(compareParsedItems);
|
|
7406
|
+
const conflictInfoByItemId = calculateConflictInfo(parsedItems);
|
|
7332
7407
|
const laneEndDays = [];
|
|
7333
7408
|
const laidOutItems = [];
|
|
7334
7409
|
for (const parsed of parsedItems) {
|
|
@@ -7342,6 +7417,7 @@ var layoutResourceTimelineItems = (resources, options) => {
|
|
|
7342
7417
|
laneEndDays[laneIndex] = endDay;
|
|
7343
7418
|
}
|
|
7344
7419
|
const { left, width } = calculateTaskBar(parsed.startDate, parsed.endDate, options.monthStart, options.dayWidth);
|
|
7420
|
+
const conflictInfo = conflictInfoByItemId.get(parsed.item.id);
|
|
7345
7421
|
laidOutItems.push({
|
|
7346
7422
|
item: parsed.item,
|
|
7347
7423
|
itemId: parsed.item.id,
|
|
@@ -7354,15 +7430,19 @@ var layoutResourceTimelineItems = (resources, options) => {
|
|
|
7354
7430
|
top: currentTop + laneIndex * options.laneHeight,
|
|
7355
7431
|
height: options.laneHeight,
|
|
7356
7432
|
startDate: parsed.startDate,
|
|
7357
|
-
endDate: parsed.endDate
|
|
7433
|
+
endDate: parsed.endDate,
|
|
7434
|
+
conflictRanges: conflictInfo?.conflictRanges ?? [],
|
|
7435
|
+
conflictsWith: conflictInfo?.conflictsWith ?? []
|
|
7358
7436
|
});
|
|
7359
7437
|
}
|
|
7360
7438
|
const laneCount = Math.max(1, laneEndDays.length);
|
|
7361
7439
|
const resourceRowHeight = laneCount * options.laneHeight;
|
|
7440
|
+
const conflictCount = laidOutItems.filter((item) => item.conflictsWith.length > 0).length;
|
|
7362
7441
|
const row = {
|
|
7363
7442
|
resource,
|
|
7364
7443
|
resourceId: resource.id,
|
|
7365
7444
|
laneCount,
|
|
7445
|
+
conflictCount,
|
|
7366
7446
|
resourceRowTop: currentTop,
|
|
7367
7447
|
resourceRowHeight
|
|
7368
7448
|
};
|
|
@@ -7371,8 +7451,8 @@ var layoutResourceTimelineItems = (resources, options) => {
|
|
|
7371
7451
|
...item,
|
|
7372
7452
|
resourceRowHeight
|
|
7373
7453
|
})));
|
|
7374
|
-
currentTop += resourceRowHeight;
|
|
7375
|
-
}
|
|
7454
|
+
currentTop += resourceRowHeight + rowGap;
|
|
7455
|
+
});
|
|
7376
7456
|
return {
|
|
7377
7457
|
rows,
|
|
7378
7458
|
items,
|
|
@@ -7389,6 +7469,56 @@ var snapToDay = (pixels, dayWidth) => {
|
|
|
7389
7469
|
var addUTCDays = (date, days) => {
|
|
7390
7470
|
return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate() + days));
|
|
7391
7471
|
};
|
|
7472
|
+
var getDayOffset2 = (date, monthStart) => {
|
|
7473
|
+
return Math.round(
|
|
7474
|
+
(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()) - Date.UTC(monthStart.getUTCFullYear(), monthStart.getUTCMonth(), monthStart.getUTCDate())) / (24 * 60 * 60 * 1e3)
|
|
7475
|
+
);
|
|
7476
|
+
};
|
|
7477
|
+
var resolveResourceMoveRange = (activeDrag, nextLeft, nextWidth) => {
|
|
7478
|
+
const dayOffset = Math.round(nextLeft / activeDrag.dayWidth);
|
|
7479
|
+
const durationDays = Math.round(nextWidth / activeDrag.dayWidth);
|
|
7480
|
+
const rawStartDate = addUTCDays(activeDrag.monthStart, dayOffset);
|
|
7481
|
+
const rawEndDate = addUTCDays(rawStartDate, durationDays - 1);
|
|
7482
|
+
if (!activeDrag.businessDays || !activeDrag.weekendPredicate) {
|
|
7483
|
+
return {
|
|
7484
|
+
startDate: rawStartDate,
|
|
7485
|
+
endDate: rawEndDate,
|
|
7486
|
+
left: nextLeft,
|
|
7487
|
+
width: nextWidth
|
|
7488
|
+
};
|
|
7489
|
+
}
|
|
7490
|
+
const range = (() => {
|
|
7491
|
+
if (activeDrag.mode === "resize-start") {
|
|
7492
|
+
const snapDirection2 = rawStartDate.getTime() >= activeDrag.startDate.getTime() ? 1 : -1;
|
|
7493
|
+
const duration = getBusinessDaysCount(rawStartDate, activeDrag.endDate, activeDrag.weekendPredicate);
|
|
7494
|
+
return buildTaskRangeFromEnd(activeDrag.endDate, duration, true, activeDrag.weekendPredicate, snapDirection2);
|
|
7495
|
+
}
|
|
7496
|
+
if (activeDrag.mode === "resize-end") {
|
|
7497
|
+
const snapDirection2 = rawEndDate.getTime() >= activeDrag.endDate.getTime() ? 1 : -1;
|
|
7498
|
+
const duration = getBusinessDaysCount(activeDrag.startDate, rawEndDate, activeDrag.weekendPredicate);
|
|
7499
|
+
return buildTaskRangeFromStart(activeDrag.startDate, duration, true, activeDrag.weekendPredicate, snapDirection2);
|
|
7500
|
+
}
|
|
7501
|
+
const dayDelta = Math.round((nextLeft - activeDrag.initialLeft) / activeDrag.dayWidth);
|
|
7502
|
+
const proposedStartDate = addUTCDays(activeDrag.startDate, dayDelta);
|
|
7503
|
+
const snapDirection = proposedStartDate.getTime() >= activeDrag.startDate.getTime() ? 1 : -1;
|
|
7504
|
+
return moveTaskRange(
|
|
7505
|
+
activeDrag.startDate,
|
|
7506
|
+
activeDrag.endDate,
|
|
7507
|
+
proposedStartDate,
|
|
7508
|
+
true,
|
|
7509
|
+
activeDrag.weekendPredicate,
|
|
7510
|
+
snapDirection
|
|
7511
|
+
);
|
|
7512
|
+
})();
|
|
7513
|
+
const startOffset = getDayOffset2(range.start, activeDrag.monthStart);
|
|
7514
|
+
const endOffset = getDayOffset2(range.end, activeDrag.monthStart);
|
|
7515
|
+
return {
|
|
7516
|
+
startDate: range.start,
|
|
7517
|
+
endDate: range.end,
|
|
7518
|
+
left: Math.round(startOffset * activeDrag.dayWidth),
|
|
7519
|
+
width: Math.round((endOffset - startOffset + 1) * activeDrag.dayWidth)
|
|
7520
|
+
};
|
|
7521
|
+
};
|
|
7392
7522
|
var resolveTargetResource = (rows, clientY, gridTop) => {
|
|
7393
7523
|
const localY = clientY - gridTop;
|
|
7394
7524
|
return rows.find(
|
|
@@ -7397,10 +7527,13 @@ var resolveTargetResource = (rows, clientY, gridTop) => {
|
|
|
7397
7527
|
};
|
|
7398
7528
|
var useResourceItemDrag = ({
|
|
7399
7529
|
dayWidth,
|
|
7530
|
+
monthStart,
|
|
7400
7531
|
rows,
|
|
7401
7532
|
gridElementRef,
|
|
7402
7533
|
readonly,
|
|
7403
7534
|
disableResourceReassignment,
|
|
7535
|
+
businessDays = false,
|
|
7536
|
+
weekendPredicate,
|
|
7404
7537
|
onResourceItemMove
|
|
7405
7538
|
}) => {
|
|
7406
7539
|
const activeDragRef = useRef7(null);
|
|
@@ -7437,14 +7570,30 @@ var useResourceItemDrag = ({
|
|
|
7437
7570
|
if (!latestDrag) {
|
|
7438
7571
|
return;
|
|
7439
7572
|
}
|
|
7440
|
-
const
|
|
7441
|
-
const
|
|
7442
|
-
|
|
7573
|
+
const snappedDelta = snapToDay(event.clientX - latestDrag.startX, latestDrag.dayWidth);
|
|
7574
|
+
const rightEdge = latestDrag.initialLeft + latestDrag.initialWidth;
|
|
7575
|
+
const nextGeometry = (() => {
|
|
7576
|
+
if (latestDrag.mode === "resize-start") {
|
|
7577
|
+
const left = Math.min(latestDrag.initialLeft + snappedDelta, rightEdge - latestDrag.dayWidth);
|
|
7578
|
+
return { left, width: rightEdge - left };
|
|
7579
|
+
}
|
|
7580
|
+
if (latestDrag.mode === "resize-end") {
|
|
7581
|
+
return { left: latestDrag.initialLeft, width: Math.max(latestDrag.dayWidth, latestDrag.initialWidth + snappedDelta) };
|
|
7582
|
+
}
|
|
7583
|
+
return { left: latestDrag.initialLeft + snappedDelta, width: latestDrag.initialWidth };
|
|
7584
|
+
})();
|
|
7585
|
+
const nextRange = resolveResourceMoveRange(latestDrag, nextGeometry.left, nextGeometry.width);
|
|
7586
|
+
const nextTop = disableResourceReassignment || latestDrag.mode !== "move" ? latestDrag.initialTop : latestDrag.initialTop + (event.clientY - latestDrag.startY);
|
|
7587
|
+
latestDrag.currentLeft = nextRange.left;
|
|
7588
|
+
latestDrag.currentWidth = nextRange.width;
|
|
7443
7589
|
latestDrag.currentTop = nextTop;
|
|
7444
7590
|
setPreview({
|
|
7445
7591
|
itemId: latestDrag.itemId,
|
|
7446
|
-
left:
|
|
7447
|
-
top: nextTop
|
|
7592
|
+
left: nextRange.left,
|
|
7593
|
+
top: nextTop,
|
|
7594
|
+
width: nextRange.width,
|
|
7595
|
+
startDate: nextRange.startDate,
|
|
7596
|
+
endDate: nextRange.endDate
|
|
7448
7597
|
});
|
|
7449
7598
|
});
|
|
7450
7599
|
};
|
|
@@ -7457,18 +7606,20 @@ var useResourceItemDrag = ({
|
|
|
7457
7606
|
activeDragRef.current = null;
|
|
7458
7607
|
setPreview(null);
|
|
7459
7608
|
const gridTop = gridElementRef?.current?.getBoundingClientRect().top ?? 0;
|
|
7460
|
-
const targetResource = disableResourceReassignment ? rowsRef.current.find((row) => row.resourceId === activeDrag.fromResourceId)?.resource ?? null : resolveTargetResource(rowsRef.current, event.clientY, gridTop);
|
|
7609
|
+
const targetResource = disableResourceReassignment || activeDrag.mode !== "move" ? rowsRef.current.find((row) => row.resourceId === activeDrag.fromResourceId)?.resource ?? null : resolveTargetResource(rowsRef.current, event.clientY, gridTop);
|
|
7461
7610
|
if (!targetResource) {
|
|
7462
7611
|
return;
|
|
7463
7612
|
}
|
|
7464
|
-
const
|
|
7613
|
+
const nextRange = resolveResourceMoveRange(activeDrag, activeDrag.currentLeft, activeDrag.currentWidth);
|
|
7465
7614
|
onResourceItemMoveRef.current?.({
|
|
7466
7615
|
item: activeDrag.item,
|
|
7467
7616
|
itemId: activeDrag.itemId,
|
|
7617
|
+
taskId: activeDrag.item.taskId,
|
|
7468
7618
|
fromResourceId: activeDrag.fromResourceId,
|
|
7469
7619
|
toResourceId: targetResource.id,
|
|
7470
|
-
startDate:
|
|
7471
|
-
endDate:
|
|
7620
|
+
startDate: nextRange.startDate,
|
|
7621
|
+
endDate: nextRange.endDate,
|
|
7622
|
+
changeType: activeDrag.mode
|
|
7472
7623
|
});
|
|
7473
7624
|
};
|
|
7474
7625
|
window.addEventListener("mousemove", handleMouseMove);
|
|
@@ -7483,27 +7634,38 @@ var useResourceItemDrag = ({
|
|
|
7483
7634
|
if (readonly || layoutItem.item.locked || event.button !== 0) {
|
|
7484
7635
|
return;
|
|
7485
7636
|
}
|
|
7637
|
+
const target = event.target;
|
|
7638
|
+
const mode = target.closest(".gantt-resourceTimeline-resizeHandleStart") ? "resize-start" : target.closest(".gantt-resourceTimeline-resizeHandleEnd") ? "resize-end" : "move";
|
|
7486
7639
|
event.preventDefault();
|
|
7487
7640
|
activeDragRef.current = {
|
|
7488
7641
|
item: layoutItem.item,
|
|
7489
7642
|
itemId: layoutItem.itemId,
|
|
7643
|
+
mode,
|
|
7490
7644
|
fromResourceId: layoutItem.resourceId,
|
|
7491
7645
|
startX: event.clientX,
|
|
7492
7646
|
startY: event.clientY,
|
|
7493
7647
|
initialLeft: layoutItem.left,
|
|
7494
7648
|
initialTop: layoutItem.top,
|
|
7649
|
+
initialWidth: layoutItem.width,
|
|
7495
7650
|
currentLeft: layoutItem.left,
|
|
7496
7651
|
currentTop: layoutItem.top,
|
|
7652
|
+
currentWidth: layoutItem.width,
|
|
7497
7653
|
dayWidth,
|
|
7498
7654
|
startDate: layoutItem.startDate,
|
|
7499
|
-
endDate: layoutItem.endDate
|
|
7655
|
+
endDate: layoutItem.endDate,
|
|
7656
|
+
monthStart,
|
|
7657
|
+
businessDays,
|
|
7658
|
+
weekendPredicate
|
|
7500
7659
|
};
|
|
7501
7660
|
setPreview({
|
|
7502
7661
|
itemId: layoutItem.itemId,
|
|
7503
7662
|
left: layoutItem.left,
|
|
7504
|
-
top: layoutItem.top
|
|
7663
|
+
top: layoutItem.top,
|
|
7664
|
+
width: layoutItem.width,
|
|
7665
|
+
startDate: layoutItem.startDate,
|
|
7666
|
+
endDate: layoutItem.endDate
|
|
7505
7667
|
});
|
|
7506
|
-
}, [dayWidth, readonly]);
|
|
7668
|
+
}, [businessDays, dayWidth, monthStart, readonly, weekendPredicate]);
|
|
7507
7669
|
return {
|
|
7508
7670
|
preview,
|
|
7509
7671
|
startDrag,
|
|
@@ -7517,6 +7679,7 @@ var DEFAULT_DAY_WIDTH = 40;
|
|
|
7517
7679
|
var DEFAULT_HEADER_HEIGHT = 40;
|
|
7518
7680
|
var DEFAULT_LANE_HEIGHT = 40;
|
|
7519
7681
|
var DEFAULT_ROW_HEADER_WIDTH = 240;
|
|
7682
|
+
var DEFAULT_RESOURCE_ROW_GAP = 8;
|
|
7520
7683
|
var ITEM_OUTER_VERTICAL_INSET = 2;
|
|
7521
7684
|
var ITEM_INNER_VERTICAL_INSET = 1;
|
|
7522
7685
|
var ITEM_HORIZONTAL_INSET = 1;
|
|
@@ -7576,16 +7739,64 @@ var getVisualItemGeometry = (geometry, laneIndex, laneCount) => {
|
|
|
7576
7739
|
height: Math.max(0, geometry.height - topInset - bottomInset)
|
|
7577
7740
|
};
|
|
7578
7741
|
};
|
|
7742
|
+
var getWeekendOverlaySegments = (startDate, endDate, dayWidth, weekendPredicate) => {
|
|
7743
|
+
const segments2 = [];
|
|
7744
|
+
const current = new Date(Date.UTC(startDate.getUTCFullYear(), startDate.getUTCMonth(), startDate.getUTCDate()));
|
|
7745
|
+
let activeStartOffset = null;
|
|
7746
|
+
let offset = 0;
|
|
7747
|
+
while (current.getTime() <= endDate.getTime()) {
|
|
7748
|
+
const isWeekendDay = weekendPredicate(current);
|
|
7749
|
+
if (isWeekendDay && activeStartOffset === null) {
|
|
7750
|
+
activeStartOffset = offset;
|
|
7751
|
+
}
|
|
7752
|
+
if (!isWeekendDay && activeStartOffset !== null) {
|
|
7753
|
+
segments2.push({
|
|
7754
|
+
left: Math.round(activeStartOffset * dayWidth),
|
|
7755
|
+
width: Math.round((offset - activeStartOffset) * dayWidth)
|
|
7756
|
+
});
|
|
7757
|
+
activeStartOffset = null;
|
|
7758
|
+
}
|
|
7759
|
+
current.setUTCDate(current.getUTCDate() + 1);
|
|
7760
|
+
offset += 1;
|
|
7761
|
+
}
|
|
7762
|
+
if (activeStartOffset !== null) {
|
|
7763
|
+
segments2.push({
|
|
7764
|
+
left: Math.round(activeStartOffset * dayWidth),
|
|
7765
|
+
width: Math.round((offset - activeStartOffset) * dayWidth)
|
|
7766
|
+
});
|
|
7767
|
+
}
|
|
7768
|
+
return segments2;
|
|
7769
|
+
};
|
|
7770
|
+
var getRangeOverlaySegments = (itemStartDate, ranges, dayWidth) => {
|
|
7771
|
+
return ranges.map((range) => {
|
|
7772
|
+
const startOffset = Math.max(0, Math.round(
|
|
7773
|
+
(Date.UTC(range.startDate.getUTCFullYear(), range.startDate.getUTCMonth(), range.startDate.getUTCDate()) - Date.UTC(itemStartDate.getUTCFullYear(), itemStartDate.getUTCMonth(), itemStartDate.getUTCDate())) / (24 * 60 * 60 * 1e3)
|
|
7774
|
+
));
|
|
7775
|
+
const endOffset = Math.max(startOffset, Math.round(
|
|
7776
|
+
(Date.UTC(range.endDate.getUTCFullYear(), range.endDate.getUTCMonth(), range.endDate.getUTCDate()) - Date.UTC(itemStartDate.getUTCFullYear(), itemStartDate.getUTCMonth(), itemStartDate.getUTCDate())) / (24 * 60 * 60 * 1e3)
|
|
7777
|
+
));
|
|
7778
|
+
return {
|
|
7779
|
+
left: Math.round(startOffset * dayWidth),
|
|
7780
|
+
width: Math.round((endOffset - startOffset + 1) * dayWidth)
|
|
7781
|
+
};
|
|
7782
|
+
});
|
|
7783
|
+
};
|
|
7784
|
+
var getDurationValue = (startDate, endDate, businessDays, weekendPredicate) => businessDays ? getBusinessDaysCount(startDate, endDate, weekendPredicate) : Math.max(1, Math.round((endDate.getTime() - startDate.getTime()) / (24 * 60 * 60 * 1e3)) + 1);
|
|
7579
7785
|
function ResourceTimelineChart({
|
|
7580
7786
|
resources,
|
|
7581
7787
|
dayWidth = DEFAULT_DAY_WIDTH,
|
|
7582
7788
|
rowHeaderWidth = DEFAULT_ROW_HEADER_WIDTH,
|
|
7583
7789
|
laneHeight = DEFAULT_LANE_HEIGHT,
|
|
7584
7790
|
headerHeight = DEFAULT_HEADER_HEIGHT,
|
|
7791
|
+
allowVerticalPan = false,
|
|
7792
|
+
customDays,
|
|
7793
|
+
isWeekend: isWeekend3,
|
|
7794
|
+
businessDays = true,
|
|
7585
7795
|
readonly,
|
|
7586
7796
|
disableResourceReassignment,
|
|
7587
7797
|
renderItem,
|
|
7588
7798
|
getItemClassName,
|
|
7799
|
+
onResourceItemClick,
|
|
7589
7800
|
onResourceItemMove
|
|
7590
7801
|
}) {
|
|
7591
7802
|
const scrollContainerRef = useRef8(null);
|
|
@@ -7599,9 +7810,18 @@ function ResourceTimelineChart({
|
|
|
7599
7810
|
const firstDay = dateRange[0] ?? /* @__PURE__ */ new Date();
|
|
7600
7811
|
return new Date(Date.UTC(firstDay.getUTCFullYear(), firstDay.getUTCMonth(), 1));
|
|
7601
7812
|
}, [dateRange]);
|
|
7813
|
+
const weekendPredicate = useMemo9(
|
|
7814
|
+
() => createCustomDayPredicate({ customDays, isWeekend: isWeekend3 }),
|
|
7815
|
+
[customDays, isWeekend3]
|
|
7816
|
+
);
|
|
7602
7817
|
const gridWidth = useMemo9(() => Math.round(dateRange.length * dayWidth), [dateRange.length, dayWidth]);
|
|
7603
7818
|
const layout = useMemo9(
|
|
7604
|
-
() => layoutResourceTimelineItems(resources, {
|
|
7819
|
+
() => layoutResourceTimelineItems(resources, {
|
|
7820
|
+
monthStart,
|
|
7821
|
+
dayWidth,
|
|
7822
|
+
laneHeight,
|
|
7823
|
+
rowGap: DEFAULT_RESOURCE_ROW_GAP
|
|
7824
|
+
}),
|
|
7605
7825
|
[resources, monthStart, dayWidth, laneHeight]
|
|
7606
7826
|
);
|
|
7607
7827
|
const todayInRange = useMemo9(() => {
|
|
@@ -7620,10 +7840,13 @@ function ResourceTimelineChart({
|
|
|
7620
7840
|
}, [layout.items]);
|
|
7621
7841
|
const { preview, startDrag } = useResourceItemDrag({
|
|
7622
7842
|
dayWidth,
|
|
7843
|
+
monthStart,
|
|
7623
7844
|
rows: layout.rows,
|
|
7624
7845
|
gridElementRef: gridRef,
|
|
7625
7846
|
readonly,
|
|
7626
7847
|
disableResourceReassignment,
|
|
7848
|
+
businessDays,
|
|
7849
|
+
weekendPredicate,
|
|
7627
7850
|
onResourceItemMove
|
|
7628
7851
|
});
|
|
7629
7852
|
const handlePanStart = useCallback7((event) => {
|
|
@@ -7662,7 +7885,9 @@ function ResourceTimelineChart({
|
|
|
7662
7885
|
return;
|
|
7663
7886
|
}
|
|
7664
7887
|
container.scrollLeft = pan.scrollX - (event.clientX - pan.startX);
|
|
7665
|
-
|
|
7888
|
+
if (allowVerticalPan) {
|
|
7889
|
+
container.scrollTop = pan.scrollY - (event.clientY - pan.startY);
|
|
7890
|
+
}
|
|
7666
7891
|
};
|
|
7667
7892
|
const handlePanEnd = () => {
|
|
7668
7893
|
if (!panStateRef.current?.active) {
|
|
@@ -7680,13 +7905,14 @@ function ResourceTimelineChart({
|
|
|
7680
7905
|
window.removeEventListener("mousemove", handlePanMove);
|
|
7681
7906
|
window.removeEventListener("mouseup", handlePanEnd);
|
|
7682
7907
|
};
|
|
7683
|
-
}, []);
|
|
7908
|
+
}, [allowVerticalPan]);
|
|
7684
7909
|
return /* @__PURE__ */ jsx15("div", { className: "gantt-container gantt-resourceTimeline", children: /* @__PURE__ */ jsx15(
|
|
7685
7910
|
"div",
|
|
7686
7911
|
{
|
|
7687
7912
|
ref: scrollContainerRef,
|
|
7688
7913
|
className: "gantt-resourceTimeline-scrollContainer",
|
|
7689
7914
|
style: { cursor: "grab" },
|
|
7915
|
+
"data-allow-vertical-pan": allowVerticalPan ? "true" : "false",
|
|
7690
7916
|
onMouseDown: handlePanStart,
|
|
7691
7917
|
children: /* @__PURE__ */ jsxs12("div", { className: "gantt-resourceTimeline-scrollContent", children: [
|
|
7692
7918
|
/* @__PURE__ */ jsxs12(
|
|
@@ -7702,13 +7928,26 @@ function ResourceTimelineChart({
|
|
|
7702
7928
|
style: { height: `${headerHeight}px` }
|
|
7703
7929
|
}
|
|
7704
7930
|
),
|
|
7705
|
-
layout.rows.map((row) => /* @__PURE__ */
|
|
7931
|
+
layout.rows.map((row) => /* @__PURE__ */ jsxs12(
|
|
7706
7932
|
"div",
|
|
7707
7933
|
{
|
|
7708
7934
|
className: "gantt-resourceTimeline-resourceHeader",
|
|
7709
7935
|
"data-resource-row-id": row.resourceId,
|
|
7710
|
-
style: {
|
|
7711
|
-
|
|
7936
|
+
style: {
|
|
7937
|
+
height: `${row.resourceRowHeight + DEFAULT_RESOURCE_ROW_GAP}px`,
|
|
7938
|
+
paddingBottom: `${DEFAULT_RESOURCE_ROW_GAP}px`
|
|
7939
|
+
},
|
|
7940
|
+
children: [
|
|
7941
|
+
/* @__PURE__ */ jsx15("span", { className: "gantt-resourceTimeline-resourceName", children: row.resource.name }),
|
|
7942
|
+
row.conflictCount > 0 && /* @__PURE__ */ jsx15(
|
|
7943
|
+
"span",
|
|
7944
|
+
{
|
|
7945
|
+
className: "gantt-resourceTimeline-conflictBadge",
|
|
7946
|
+
"aria-label": `${row.conflictCount} \u043A\u043E\u043D\u0444\u043B\u0438\u043A\u0442\u043E\u0432`,
|
|
7947
|
+
children: row.conflictCount
|
|
7948
|
+
}
|
|
7949
|
+
)
|
|
7950
|
+
]
|
|
7712
7951
|
},
|
|
7713
7952
|
row.resourceId
|
|
7714
7953
|
))
|
|
@@ -7721,7 +7960,15 @@ function ResourceTimelineChart({
|
|
|
7721
7960
|
className: "gantt-resourceTimeline-chartSurface",
|
|
7722
7961
|
style: { minWidth: `${gridWidth}px` },
|
|
7723
7962
|
children: [
|
|
7724
|
-
/* @__PURE__ */ jsx15("div", { className: "gantt-resourceTimeline-stickyHeader", style: { width: `${gridWidth}px` }, children: /* @__PURE__ */ jsx15(
|
|
7963
|
+
/* @__PURE__ */ jsx15("div", { className: "gantt-resourceTimeline-stickyHeader", style: { width: `${gridWidth}px` }, children: /* @__PURE__ */ jsx15(
|
|
7964
|
+
TimeScaleHeader_default,
|
|
7965
|
+
{
|
|
7966
|
+
days: dateRange,
|
|
7967
|
+
dayWidth,
|
|
7968
|
+
headerHeight,
|
|
7969
|
+
isCustomWeekend: weekendPredicate
|
|
7970
|
+
}
|
|
7971
|
+
) }),
|
|
7725
7972
|
/* @__PURE__ */ jsxs12(
|
|
7726
7973
|
"div",
|
|
7727
7974
|
{
|
|
@@ -7729,7 +7976,15 @@ function ResourceTimelineChart({
|
|
|
7729
7976
|
className: "gantt-resourceTimeline-grid",
|
|
7730
7977
|
style: { width: `${gridWidth}px`, height: `${layout.totalHeight}px` },
|
|
7731
7978
|
children: [
|
|
7732
|
-
/* @__PURE__ */ jsx15(
|
|
7979
|
+
/* @__PURE__ */ jsx15(
|
|
7980
|
+
GridBackground_default,
|
|
7981
|
+
{
|
|
7982
|
+
dateRange,
|
|
7983
|
+
dayWidth,
|
|
7984
|
+
totalHeight: layout.totalHeight,
|
|
7985
|
+
isCustomWeekend: weekendPredicate
|
|
7986
|
+
}
|
|
7987
|
+
),
|
|
7733
7988
|
todayInRange && /* @__PURE__ */ jsx15(TodayIndicator_default, { monthStart, dayWidth }),
|
|
7734
7989
|
layout.rows.map((row) => /* @__PURE__ */ jsx15(
|
|
7735
7990
|
"div",
|
|
@@ -7738,7 +7993,7 @@ function ResourceTimelineChart({
|
|
|
7738
7993
|
"data-resource-row-id": row.resourceId,
|
|
7739
7994
|
style: {
|
|
7740
7995
|
top: `${row.resourceRowTop}px`,
|
|
7741
|
-
height: `${row.resourceRowHeight}px`
|
|
7996
|
+
height: `${row.resourceRowHeight + DEFAULT_RESOURCE_ROW_GAP}px`
|
|
7742
7997
|
}
|
|
7743
7998
|
},
|
|
7744
7999
|
row.resourceId
|
|
@@ -7746,17 +8001,18 @@ function ResourceTimelineChart({
|
|
|
7746
8001
|
Array.from(itemsByResourceId.values()).flatMap(
|
|
7747
8002
|
(resourceItems) => resourceItems.map((layoutItem) => {
|
|
7748
8003
|
const customClassName = getItemClassName?.(layoutItem.item);
|
|
8004
|
+
const isDraggingItem = preview?.itemId === layoutItem.itemId;
|
|
7749
8005
|
const className = [
|
|
7750
8006
|
"gantt-resourceTimeline-item",
|
|
7751
|
-
|
|
8007
|
+
isDraggingItem && "gantt-resourceTimeline-itemDragging",
|
|
7752
8008
|
(readonly || layoutItem.item.locked) && "gantt-resourceTimeline-itemDisabled",
|
|
7753
8009
|
customClassName
|
|
7754
8010
|
].filter(Boolean).join(" ");
|
|
7755
8011
|
const laneCount = Math.max(1, Math.round(layoutItem.resourceRowHeight / layoutItem.height));
|
|
7756
|
-
const previewStyle =
|
|
8012
|
+
const previewStyle = isDraggingItem ? getVisualItemGeometry({
|
|
7757
8013
|
left: preview.left,
|
|
7758
8014
|
top: preview.top,
|
|
7759
|
-
width:
|
|
8015
|
+
width: preview.width,
|
|
7760
8016
|
height: layoutItem.height
|
|
7761
8017
|
}, layoutItem.laneIndex, laneCount) : void 0;
|
|
7762
8018
|
const itemGeometry = getVisualItemGeometry({
|
|
@@ -7765,25 +8021,96 @@ function ResourceTimelineChart({
|
|
|
7765
8021
|
width: layoutItem.width,
|
|
7766
8022
|
height: layoutItem.height
|
|
7767
8023
|
}, layoutItem.laneIndex, laneCount);
|
|
7768
|
-
|
|
8024
|
+
const overlayStartDate = isDraggingItem ? preview.startDate : layoutItem.startDate;
|
|
8025
|
+
const overlayEndDate = isDraggingItem ? preview.endDate : layoutItem.endDate;
|
|
8026
|
+
const weekendOverlaySegments = businessDays ? getWeekendOverlaySegments(overlayStartDate, overlayEndDate, dayWidth, weekendPredicate) : [];
|
|
8027
|
+
const conflictOverlaySegments = getRangeOverlaySegments(
|
|
8028
|
+
overlayStartDate,
|
|
8029
|
+
isDraggingItem ? [] : layoutItem.conflictRanges,
|
|
8030
|
+
dayWidth
|
|
8031
|
+
);
|
|
8032
|
+
const durationValue = getDurationValue(
|
|
8033
|
+
overlayStartDate,
|
|
8034
|
+
overlayEndDate,
|
|
8035
|
+
businessDays,
|
|
8036
|
+
weekendPredicate
|
|
8037
|
+
);
|
|
8038
|
+
const renderContext = {
|
|
8039
|
+
startDate: overlayStartDate,
|
|
8040
|
+
endDate: overlayEndDate,
|
|
8041
|
+
durationDays: durationValue,
|
|
8042
|
+
isDragging: isDraggingItem
|
|
8043
|
+
};
|
|
8044
|
+
return /* @__PURE__ */ jsxs12(
|
|
7769
8045
|
"div",
|
|
7770
8046
|
{
|
|
7771
8047
|
className,
|
|
7772
8048
|
"data-resource-item-id": layoutItem.itemId,
|
|
7773
8049
|
onMouseDown: (event) => startDrag(event, layoutItem),
|
|
8050
|
+
onClick: () => onResourceItemClick?.(layoutItem.item),
|
|
8051
|
+
onKeyDown: (event) => {
|
|
8052
|
+
if (!onResourceItemClick) {
|
|
8053
|
+
return;
|
|
8054
|
+
}
|
|
8055
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
8056
|
+
event.preventDefault();
|
|
8057
|
+
onResourceItemClick(layoutItem.item);
|
|
8058
|
+
}
|
|
8059
|
+
},
|
|
8060
|
+
role: onResourceItemClick ? "button" : void 0,
|
|
8061
|
+
tabIndex: onResourceItemClick ? 0 : void 0,
|
|
7774
8062
|
style: {
|
|
7775
8063
|
left: `${itemGeometry.left}px`,
|
|
7776
8064
|
top: `${itemGeometry.top}px`,
|
|
7777
|
-
...previewStyle,
|
|
7778
8065
|
width: `${itemGeometry.width}px`,
|
|
7779
8066
|
height: `${itemGeometry.height}px`,
|
|
8067
|
+
...previewStyle,
|
|
7780
8068
|
backgroundColor: layoutItem.item.color ?? "var(--gantt-task-bar-default-color, #3b82f6)"
|
|
7781
8069
|
},
|
|
7782
|
-
children:
|
|
7783
|
-
/* @__PURE__ */
|
|
7784
|
-
|
|
7785
|
-
|
|
7786
|
-
|
|
8070
|
+
children: [
|
|
8071
|
+
!readonly && !layoutItem.item.locked && /* @__PURE__ */ jsxs12(Fragment3, { children: [
|
|
8072
|
+
/* @__PURE__ */ jsx15("span", { className: "gantt-resourceTimeline-resizeHandle gantt-resourceTimeline-resizeHandleStart" }),
|
|
8073
|
+
/* @__PURE__ */ jsx15("span", { className: "gantt-resourceTimeline-resizeHandle gantt-resourceTimeline-resizeHandleEnd" })
|
|
8074
|
+
] }),
|
|
8075
|
+
weekendOverlaySegments.map((segment, index) => /* @__PURE__ */ jsx15(
|
|
8076
|
+
"span",
|
|
8077
|
+
{
|
|
8078
|
+
className: "gantt-resourceTimeline-weekendOverlay",
|
|
8079
|
+
"data-resource-weekend-overlay": "true",
|
|
8080
|
+
style: {
|
|
8081
|
+
left: `${segment.left}px`,
|
|
8082
|
+
width: `${segment.width}px`
|
|
8083
|
+
}
|
|
8084
|
+
},
|
|
8085
|
+
`weekend-overlay-${index}`
|
|
8086
|
+
)),
|
|
8087
|
+
conflictOverlaySegments.map((segment, index) => /* @__PURE__ */ jsx15(
|
|
8088
|
+
"span",
|
|
8089
|
+
{
|
|
8090
|
+
className: "gantt-resourceTimeline-conflictOverlay",
|
|
8091
|
+
"data-resource-conflict-overlay": "true",
|
|
8092
|
+
style: {
|
|
8093
|
+
left: `${segment.left}px`,
|
|
8094
|
+
width: `${segment.width}px`
|
|
8095
|
+
}
|
|
8096
|
+
},
|
|
8097
|
+
`conflict-overlay-${index}`
|
|
8098
|
+
)),
|
|
8099
|
+
/* @__PURE__ */ jsx15("div", { className: "gantt-resourceTimeline-itemInner", children: renderItem ? renderItem(layoutItem.item, renderContext) : /* @__PURE__ */ jsxs12("div", { className: "gantt-resourceTimeline-defaultItemContent", children: [
|
|
8100
|
+
/* @__PURE__ */ jsxs12("div", { className: "gantt-resourceTimeline-defaultItemMain", children: [
|
|
8101
|
+
/* @__PURE__ */ jsx15(
|
|
8102
|
+
"span",
|
|
8103
|
+
{
|
|
8104
|
+
className: "gantt-resourceTimeline-itemDurationChip",
|
|
8105
|
+
"aria-label": `${durationValue} \u0434`,
|
|
8106
|
+
children: durationValue
|
|
8107
|
+
}
|
|
8108
|
+
),
|
|
8109
|
+
/* @__PURE__ */ jsx15("span", { className: "gantt-resourceTimeline-itemTitle", children: layoutItem.item.title })
|
|
8110
|
+
] }),
|
|
8111
|
+
layoutItem.item.subtitle && /* @__PURE__ */ jsx15("span", { className: "gantt-resourceTimeline-itemSubtitle", children: layoutItem.item.subtitle })
|
|
8112
|
+
] }) })
|
|
8113
|
+
]
|
|
7787
8114
|
},
|
|
7788
8115
|
layoutItem.itemId
|
|
7789
8116
|
);
|