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.js
CHANGED
|
@@ -7402,12 +7402,86 @@ var compareParsedItems = (a, b) => {
|
|
|
7402
7402
|
}
|
|
7403
7403
|
return a.item.id.localeCompare(b.item.id);
|
|
7404
7404
|
};
|
|
7405
|
+
var getOverlapRange = (left, right) => {
|
|
7406
|
+
const startDay = Math.max(getUTCDayNumber(left.startDate), getUTCDayNumber(right.startDate));
|
|
7407
|
+
const endDay = Math.min(getUTCDayNumber(left.endDate), getUTCDayNumber(right.endDate));
|
|
7408
|
+
if (startDay > endDay) {
|
|
7409
|
+
return null;
|
|
7410
|
+
}
|
|
7411
|
+
return {
|
|
7412
|
+
startDate: new Date(startDay * 864e5),
|
|
7413
|
+
endDate: new Date(endDay * 864e5),
|
|
7414
|
+
itemIds: [left.item.id, right.item.id]
|
|
7415
|
+
};
|
|
7416
|
+
};
|
|
7417
|
+
var mergeConflictRanges = (ranges) => {
|
|
7418
|
+
const sortedRanges = [...ranges].sort(
|
|
7419
|
+
(left, right) => getUTCDayNumber(left.startDate) - getUTCDayNumber(right.startDate) || getUTCDayNumber(left.endDate) - getUTCDayNumber(right.endDate)
|
|
7420
|
+
);
|
|
7421
|
+
const merged = [];
|
|
7422
|
+
for (const range of sortedRanges) {
|
|
7423
|
+
const previous = merged[merged.length - 1];
|
|
7424
|
+
const rangeStartDay = getUTCDayNumber(range.startDate);
|
|
7425
|
+
const rangeEndDay = getUTCDayNumber(range.endDate);
|
|
7426
|
+
if (!previous || rangeStartDay > getUTCDayNumber(previous.endDate) + 1) {
|
|
7427
|
+
merged.push({
|
|
7428
|
+
startDate: range.startDate,
|
|
7429
|
+
endDate: range.endDate,
|
|
7430
|
+
itemIds: [...range.itemIds]
|
|
7431
|
+
});
|
|
7432
|
+
continue;
|
|
7433
|
+
}
|
|
7434
|
+
if (rangeEndDay > getUTCDayNumber(previous.endDate)) {
|
|
7435
|
+
previous.endDate = range.endDate;
|
|
7436
|
+
}
|
|
7437
|
+
previous.itemIds = Array.from(/* @__PURE__ */ new Set([...previous.itemIds, ...range.itemIds])).sort();
|
|
7438
|
+
}
|
|
7439
|
+
return merged;
|
|
7440
|
+
};
|
|
7441
|
+
var calculateConflictInfo = (parsedItems) => {
|
|
7442
|
+
const conflictRangesByItemId = /* @__PURE__ */ new Map();
|
|
7443
|
+
const conflictsWithByItemId = /* @__PURE__ */ new Map();
|
|
7444
|
+
for (let i = 0; i < parsedItems.length; i++) {
|
|
7445
|
+
for (let j = i + 1; j < parsedItems.length; j++) {
|
|
7446
|
+
const left = parsedItems[i];
|
|
7447
|
+
const right = parsedItems[j];
|
|
7448
|
+
if (getUTCDayNumber(right.startDate) > getUTCDayNumber(left.endDate)) {
|
|
7449
|
+
break;
|
|
7450
|
+
}
|
|
7451
|
+
const overlap = getOverlapRange(left, right);
|
|
7452
|
+
if (!overlap) {
|
|
7453
|
+
continue;
|
|
7454
|
+
}
|
|
7455
|
+
const leftRanges = conflictRangesByItemId.get(left.item.id) ?? [];
|
|
7456
|
+
const rightRanges = conflictRangesByItemId.get(right.item.id) ?? [];
|
|
7457
|
+
leftRanges.push(overlap);
|
|
7458
|
+
rightRanges.push(overlap);
|
|
7459
|
+
conflictRangesByItemId.set(left.item.id, leftRanges);
|
|
7460
|
+
conflictRangesByItemId.set(right.item.id, rightRanges);
|
|
7461
|
+
const leftConflicts = conflictsWithByItemId.get(left.item.id) ?? /* @__PURE__ */ new Set();
|
|
7462
|
+
const rightConflicts = conflictsWithByItemId.get(right.item.id) ?? /* @__PURE__ */ new Set();
|
|
7463
|
+
leftConflicts.add(right.item.id);
|
|
7464
|
+
rightConflicts.add(left.item.id);
|
|
7465
|
+
conflictsWithByItemId.set(left.item.id, leftConflicts);
|
|
7466
|
+
conflictsWithByItemId.set(right.item.id, rightConflicts);
|
|
7467
|
+
}
|
|
7468
|
+
}
|
|
7469
|
+
const result = /* @__PURE__ */ new Map();
|
|
7470
|
+
for (const parsedItem of parsedItems) {
|
|
7471
|
+
result.set(parsedItem.item.id, {
|
|
7472
|
+
conflictRanges: mergeConflictRanges(conflictRangesByItemId.get(parsedItem.item.id) ?? []),
|
|
7473
|
+
conflictsWith: Array.from(conflictsWithByItemId.get(parsedItem.item.id) ?? []).sort()
|
|
7474
|
+
});
|
|
7475
|
+
}
|
|
7476
|
+
return result;
|
|
7477
|
+
};
|
|
7405
7478
|
var layoutResourceTimelineItems = (resources, options) => {
|
|
7406
7479
|
const rows = [];
|
|
7407
7480
|
const items = [];
|
|
7408
7481
|
const diagnostics = [];
|
|
7409
7482
|
let currentTop = 0;
|
|
7410
|
-
|
|
7483
|
+
const rowGap = options.rowGap ?? 0;
|
|
7484
|
+
resources.forEach((resource, resourceIndex) => {
|
|
7411
7485
|
const parsedItems = [];
|
|
7412
7486
|
for (const item of resource.items) {
|
|
7413
7487
|
try {
|
|
@@ -7426,6 +7500,7 @@ var layoutResourceTimelineItems = (resources, options) => {
|
|
|
7426
7500
|
}
|
|
7427
7501
|
}
|
|
7428
7502
|
parsedItems.sort(compareParsedItems);
|
|
7503
|
+
const conflictInfoByItemId = calculateConflictInfo(parsedItems);
|
|
7429
7504
|
const laneEndDays = [];
|
|
7430
7505
|
const laidOutItems = [];
|
|
7431
7506
|
for (const parsed of parsedItems) {
|
|
@@ -7439,6 +7514,7 @@ var layoutResourceTimelineItems = (resources, options) => {
|
|
|
7439
7514
|
laneEndDays[laneIndex] = endDay;
|
|
7440
7515
|
}
|
|
7441
7516
|
const { left, width } = calculateTaskBar(parsed.startDate, parsed.endDate, options.monthStart, options.dayWidth);
|
|
7517
|
+
const conflictInfo = conflictInfoByItemId.get(parsed.item.id);
|
|
7442
7518
|
laidOutItems.push({
|
|
7443
7519
|
item: parsed.item,
|
|
7444
7520
|
itemId: parsed.item.id,
|
|
@@ -7451,15 +7527,19 @@ var layoutResourceTimelineItems = (resources, options) => {
|
|
|
7451
7527
|
top: currentTop + laneIndex * options.laneHeight,
|
|
7452
7528
|
height: options.laneHeight,
|
|
7453
7529
|
startDate: parsed.startDate,
|
|
7454
|
-
endDate: parsed.endDate
|
|
7530
|
+
endDate: parsed.endDate,
|
|
7531
|
+
conflictRanges: conflictInfo?.conflictRanges ?? [],
|
|
7532
|
+
conflictsWith: conflictInfo?.conflictsWith ?? []
|
|
7455
7533
|
});
|
|
7456
7534
|
}
|
|
7457
7535
|
const laneCount = Math.max(1, laneEndDays.length);
|
|
7458
7536
|
const resourceRowHeight = laneCount * options.laneHeight;
|
|
7537
|
+
const conflictCount = laidOutItems.filter((item) => item.conflictsWith.length > 0).length;
|
|
7459
7538
|
const row = {
|
|
7460
7539
|
resource,
|
|
7461
7540
|
resourceId: resource.id,
|
|
7462
7541
|
laneCount,
|
|
7542
|
+
conflictCount,
|
|
7463
7543
|
resourceRowTop: currentTop,
|
|
7464
7544
|
resourceRowHeight
|
|
7465
7545
|
};
|
|
@@ -7468,8 +7548,8 @@ var layoutResourceTimelineItems = (resources, options) => {
|
|
|
7468
7548
|
...item,
|
|
7469
7549
|
resourceRowHeight
|
|
7470
7550
|
})));
|
|
7471
|
-
currentTop += resourceRowHeight;
|
|
7472
|
-
}
|
|
7551
|
+
currentTop += resourceRowHeight + rowGap;
|
|
7552
|
+
});
|
|
7473
7553
|
return {
|
|
7474
7554
|
rows,
|
|
7475
7555
|
items,
|
|
@@ -7486,6 +7566,56 @@ var snapToDay = (pixels, dayWidth) => {
|
|
|
7486
7566
|
var addUTCDays = (date, days) => {
|
|
7487
7567
|
return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate() + days));
|
|
7488
7568
|
};
|
|
7569
|
+
var getDayOffset2 = (date, monthStart) => {
|
|
7570
|
+
return Math.round(
|
|
7571
|
+
(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()) - Date.UTC(monthStart.getUTCFullYear(), monthStart.getUTCMonth(), monthStart.getUTCDate())) / (24 * 60 * 60 * 1e3)
|
|
7572
|
+
);
|
|
7573
|
+
};
|
|
7574
|
+
var resolveResourceMoveRange = (activeDrag, nextLeft, nextWidth) => {
|
|
7575
|
+
const dayOffset = Math.round(nextLeft / activeDrag.dayWidth);
|
|
7576
|
+
const durationDays = Math.round(nextWidth / activeDrag.dayWidth);
|
|
7577
|
+
const rawStartDate = addUTCDays(activeDrag.monthStart, dayOffset);
|
|
7578
|
+
const rawEndDate = addUTCDays(rawStartDate, durationDays - 1);
|
|
7579
|
+
if (!activeDrag.businessDays || !activeDrag.weekendPredicate) {
|
|
7580
|
+
return {
|
|
7581
|
+
startDate: rawStartDate,
|
|
7582
|
+
endDate: rawEndDate,
|
|
7583
|
+
left: nextLeft,
|
|
7584
|
+
width: nextWidth
|
|
7585
|
+
};
|
|
7586
|
+
}
|
|
7587
|
+
const range = (() => {
|
|
7588
|
+
if (activeDrag.mode === "resize-start") {
|
|
7589
|
+
const snapDirection2 = rawStartDate.getTime() >= activeDrag.startDate.getTime() ? 1 : -1;
|
|
7590
|
+
const duration = getBusinessDaysCount(rawStartDate, activeDrag.endDate, activeDrag.weekendPredicate);
|
|
7591
|
+
return buildTaskRangeFromEnd(activeDrag.endDate, duration, true, activeDrag.weekendPredicate, snapDirection2);
|
|
7592
|
+
}
|
|
7593
|
+
if (activeDrag.mode === "resize-end") {
|
|
7594
|
+
const snapDirection2 = rawEndDate.getTime() >= activeDrag.endDate.getTime() ? 1 : -1;
|
|
7595
|
+
const duration = getBusinessDaysCount(activeDrag.startDate, rawEndDate, activeDrag.weekendPredicate);
|
|
7596
|
+
return buildTaskRangeFromStart(activeDrag.startDate, duration, true, activeDrag.weekendPredicate, snapDirection2);
|
|
7597
|
+
}
|
|
7598
|
+
const dayDelta = Math.round((nextLeft - activeDrag.initialLeft) / activeDrag.dayWidth);
|
|
7599
|
+
const proposedStartDate = addUTCDays(activeDrag.startDate, dayDelta);
|
|
7600
|
+
const snapDirection = proposedStartDate.getTime() >= activeDrag.startDate.getTime() ? 1 : -1;
|
|
7601
|
+
return moveTaskRange(
|
|
7602
|
+
activeDrag.startDate,
|
|
7603
|
+
activeDrag.endDate,
|
|
7604
|
+
proposedStartDate,
|
|
7605
|
+
true,
|
|
7606
|
+
activeDrag.weekendPredicate,
|
|
7607
|
+
snapDirection
|
|
7608
|
+
);
|
|
7609
|
+
})();
|
|
7610
|
+
const startOffset = getDayOffset2(range.start, activeDrag.monthStart);
|
|
7611
|
+
const endOffset = getDayOffset2(range.end, activeDrag.monthStart);
|
|
7612
|
+
return {
|
|
7613
|
+
startDate: range.start,
|
|
7614
|
+
endDate: range.end,
|
|
7615
|
+
left: Math.round(startOffset * activeDrag.dayWidth),
|
|
7616
|
+
width: Math.round((endOffset - startOffset + 1) * activeDrag.dayWidth)
|
|
7617
|
+
};
|
|
7618
|
+
};
|
|
7489
7619
|
var resolveTargetResource = (rows, clientY, gridTop) => {
|
|
7490
7620
|
const localY = clientY - gridTop;
|
|
7491
7621
|
return rows.find(
|
|
@@ -7494,10 +7624,13 @@ var resolveTargetResource = (rows, clientY, gridTop) => {
|
|
|
7494
7624
|
};
|
|
7495
7625
|
var useResourceItemDrag = ({
|
|
7496
7626
|
dayWidth,
|
|
7627
|
+
monthStart,
|
|
7497
7628
|
rows,
|
|
7498
7629
|
gridElementRef,
|
|
7499
7630
|
readonly,
|
|
7500
7631
|
disableResourceReassignment,
|
|
7632
|
+
businessDays = false,
|
|
7633
|
+
weekendPredicate,
|
|
7501
7634
|
onResourceItemMove
|
|
7502
7635
|
}) => {
|
|
7503
7636
|
const activeDragRef = (0, import_react13.useRef)(null);
|
|
@@ -7534,14 +7667,30 @@ var useResourceItemDrag = ({
|
|
|
7534
7667
|
if (!latestDrag) {
|
|
7535
7668
|
return;
|
|
7536
7669
|
}
|
|
7537
|
-
const
|
|
7538
|
-
const
|
|
7539
|
-
|
|
7670
|
+
const snappedDelta = snapToDay(event.clientX - latestDrag.startX, latestDrag.dayWidth);
|
|
7671
|
+
const rightEdge = latestDrag.initialLeft + latestDrag.initialWidth;
|
|
7672
|
+
const nextGeometry = (() => {
|
|
7673
|
+
if (latestDrag.mode === "resize-start") {
|
|
7674
|
+
const left = Math.min(latestDrag.initialLeft + snappedDelta, rightEdge - latestDrag.dayWidth);
|
|
7675
|
+
return { left, width: rightEdge - left };
|
|
7676
|
+
}
|
|
7677
|
+
if (latestDrag.mode === "resize-end") {
|
|
7678
|
+
return { left: latestDrag.initialLeft, width: Math.max(latestDrag.dayWidth, latestDrag.initialWidth + snappedDelta) };
|
|
7679
|
+
}
|
|
7680
|
+
return { left: latestDrag.initialLeft + snappedDelta, width: latestDrag.initialWidth };
|
|
7681
|
+
})();
|
|
7682
|
+
const nextRange = resolveResourceMoveRange(latestDrag, nextGeometry.left, nextGeometry.width);
|
|
7683
|
+
const nextTop = disableResourceReassignment || latestDrag.mode !== "move" ? latestDrag.initialTop : latestDrag.initialTop + (event.clientY - latestDrag.startY);
|
|
7684
|
+
latestDrag.currentLeft = nextRange.left;
|
|
7685
|
+
latestDrag.currentWidth = nextRange.width;
|
|
7540
7686
|
latestDrag.currentTop = nextTop;
|
|
7541
7687
|
setPreview({
|
|
7542
7688
|
itemId: latestDrag.itemId,
|
|
7543
|
-
left:
|
|
7544
|
-
top: nextTop
|
|
7689
|
+
left: nextRange.left,
|
|
7690
|
+
top: nextTop,
|
|
7691
|
+
width: nextRange.width,
|
|
7692
|
+
startDate: nextRange.startDate,
|
|
7693
|
+
endDate: nextRange.endDate
|
|
7545
7694
|
});
|
|
7546
7695
|
});
|
|
7547
7696
|
};
|
|
@@ -7554,18 +7703,20 @@ var useResourceItemDrag = ({
|
|
|
7554
7703
|
activeDragRef.current = null;
|
|
7555
7704
|
setPreview(null);
|
|
7556
7705
|
const gridTop = gridElementRef?.current?.getBoundingClientRect().top ?? 0;
|
|
7557
|
-
const targetResource = disableResourceReassignment ? rowsRef.current.find((row) => row.resourceId === activeDrag.fromResourceId)?.resource ?? null : resolveTargetResource(rowsRef.current, event.clientY, gridTop);
|
|
7706
|
+
const targetResource = disableResourceReassignment || activeDrag.mode !== "move" ? rowsRef.current.find((row) => row.resourceId === activeDrag.fromResourceId)?.resource ?? null : resolveTargetResource(rowsRef.current, event.clientY, gridTop);
|
|
7558
7707
|
if (!targetResource) {
|
|
7559
7708
|
return;
|
|
7560
7709
|
}
|
|
7561
|
-
const
|
|
7710
|
+
const nextRange = resolveResourceMoveRange(activeDrag, activeDrag.currentLeft, activeDrag.currentWidth);
|
|
7562
7711
|
onResourceItemMoveRef.current?.({
|
|
7563
7712
|
item: activeDrag.item,
|
|
7564
7713
|
itemId: activeDrag.itemId,
|
|
7714
|
+
taskId: activeDrag.item.taskId,
|
|
7565
7715
|
fromResourceId: activeDrag.fromResourceId,
|
|
7566
7716
|
toResourceId: targetResource.id,
|
|
7567
|
-
startDate:
|
|
7568
|
-
endDate:
|
|
7717
|
+
startDate: nextRange.startDate,
|
|
7718
|
+
endDate: nextRange.endDate,
|
|
7719
|
+
changeType: activeDrag.mode
|
|
7569
7720
|
});
|
|
7570
7721
|
};
|
|
7571
7722
|
window.addEventListener("mousemove", handleMouseMove);
|
|
@@ -7580,27 +7731,38 @@ var useResourceItemDrag = ({
|
|
|
7580
7731
|
if (readonly || layoutItem.item.locked || event.button !== 0) {
|
|
7581
7732
|
return;
|
|
7582
7733
|
}
|
|
7734
|
+
const target = event.target;
|
|
7735
|
+
const mode = target.closest(".gantt-resourceTimeline-resizeHandleStart") ? "resize-start" : target.closest(".gantt-resourceTimeline-resizeHandleEnd") ? "resize-end" : "move";
|
|
7583
7736
|
event.preventDefault();
|
|
7584
7737
|
activeDragRef.current = {
|
|
7585
7738
|
item: layoutItem.item,
|
|
7586
7739
|
itemId: layoutItem.itemId,
|
|
7740
|
+
mode,
|
|
7587
7741
|
fromResourceId: layoutItem.resourceId,
|
|
7588
7742
|
startX: event.clientX,
|
|
7589
7743
|
startY: event.clientY,
|
|
7590
7744
|
initialLeft: layoutItem.left,
|
|
7591
7745
|
initialTop: layoutItem.top,
|
|
7746
|
+
initialWidth: layoutItem.width,
|
|
7592
7747
|
currentLeft: layoutItem.left,
|
|
7593
7748
|
currentTop: layoutItem.top,
|
|
7749
|
+
currentWidth: layoutItem.width,
|
|
7594
7750
|
dayWidth,
|
|
7595
7751
|
startDate: layoutItem.startDate,
|
|
7596
|
-
endDate: layoutItem.endDate
|
|
7752
|
+
endDate: layoutItem.endDate,
|
|
7753
|
+
monthStart,
|
|
7754
|
+
businessDays,
|
|
7755
|
+
weekendPredicate
|
|
7597
7756
|
};
|
|
7598
7757
|
setPreview({
|
|
7599
7758
|
itemId: layoutItem.itemId,
|
|
7600
7759
|
left: layoutItem.left,
|
|
7601
|
-
top: layoutItem.top
|
|
7760
|
+
top: layoutItem.top,
|
|
7761
|
+
width: layoutItem.width,
|
|
7762
|
+
startDate: layoutItem.startDate,
|
|
7763
|
+
endDate: layoutItem.endDate
|
|
7602
7764
|
});
|
|
7603
|
-
}, [dayWidth, readonly]);
|
|
7765
|
+
}, [businessDays, dayWidth, monthStart, readonly, weekendPredicate]);
|
|
7604
7766
|
return {
|
|
7605
7767
|
preview,
|
|
7606
7768
|
startDrag,
|
|
@@ -7614,6 +7776,7 @@ var DEFAULT_DAY_WIDTH = 40;
|
|
|
7614
7776
|
var DEFAULT_HEADER_HEIGHT = 40;
|
|
7615
7777
|
var DEFAULT_LANE_HEIGHT = 40;
|
|
7616
7778
|
var DEFAULT_ROW_HEADER_WIDTH = 240;
|
|
7779
|
+
var DEFAULT_RESOURCE_ROW_GAP = 8;
|
|
7617
7780
|
var ITEM_OUTER_VERTICAL_INSET = 2;
|
|
7618
7781
|
var ITEM_INNER_VERTICAL_INSET = 1;
|
|
7619
7782
|
var ITEM_HORIZONTAL_INSET = 1;
|
|
@@ -7673,16 +7836,64 @@ var getVisualItemGeometry = (geometry, laneIndex, laneCount) => {
|
|
|
7673
7836
|
height: Math.max(0, geometry.height - topInset - bottomInset)
|
|
7674
7837
|
};
|
|
7675
7838
|
};
|
|
7839
|
+
var getWeekendOverlaySegments = (startDate, endDate, dayWidth, weekendPredicate) => {
|
|
7840
|
+
const segments2 = [];
|
|
7841
|
+
const current = new Date(Date.UTC(startDate.getUTCFullYear(), startDate.getUTCMonth(), startDate.getUTCDate()));
|
|
7842
|
+
let activeStartOffset = null;
|
|
7843
|
+
let offset = 0;
|
|
7844
|
+
while (current.getTime() <= endDate.getTime()) {
|
|
7845
|
+
const isWeekendDay = weekendPredicate(current);
|
|
7846
|
+
if (isWeekendDay && activeStartOffset === null) {
|
|
7847
|
+
activeStartOffset = offset;
|
|
7848
|
+
}
|
|
7849
|
+
if (!isWeekendDay && activeStartOffset !== null) {
|
|
7850
|
+
segments2.push({
|
|
7851
|
+
left: Math.round(activeStartOffset * dayWidth),
|
|
7852
|
+
width: Math.round((offset - activeStartOffset) * dayWidth)
|
|
7853
|
+
});
|
|
7854
|
+
activeStartOffset = null;
|
|
7855
|
+
}
|
|
7856
|
+
current.setUTCDate(current.getUTCDate() + 1);
|
|
7857
|
+
offset += 1;
|
|
7858
|
+
}
|
|
7859
|
+
if (activeStartOffset !== null) {
|
|
7860
|
+
segments2.push({
|
|
7861
|
+
left: Math.round(activeStartOffset * dayWidth),
|
|
7862
|
+
width: Math.round((offset - activeStartOffset) * dayWidth)
|
|
7863
|
+
});
|
|
7864
|
+
}
|
|
7865
|
+
return segments2;
|
|
7866
|
+
};
|
|
7867
|
+
var getRangeOverlaySegments = (itemStartDate, ranges, dayWidth) => {
|
|
7868
|
+
return ranges.map((range) => {
|
|
7869
|
+
const startOffset = Math.max(0, Math.round(
|
|
7870
|
+
(Date.UTC(range.startDate.getUTCFullYear(), range.startDate.getUTCMonth(), range.startDate.getUTCDate()) - Date.UTC(itemStartDate.getUTCFullYear(), itemStartDate.getUTCMonth(), itemStartDate.getUTCDate())) / (24 * 60 * 60 * 1e3)
|
|
7871
|
+
));
|
|
7872
|
+
const endOffset = Math.max(startOffset, Math.round(
|
|
7873
|
+
(Date.UTC(range.endDate.getUTCFullYear(), range.endDate.getUTCMonth(), range.endDate.getUTCDate()) - Date.UTC(itemStartDate.getUTCFullYear(), itemStartDate.getUTCMonth(), itemStartDate.getUTCDate())) / (24 * 60 * 60 * 1e3)
|
|
7874
|
+
));
|
|
7875
|
+
return {
|
|
7876
|
+
left: Math.round(startOffset * dayWidth),
|
|
7877
|
+
width: Math.round((endOffset - startOffset + 1) * dayWidth)
|
|
7878
|
+
};
|
|
7879
|
+
});
|
|
7880
|
+
};
|
|
7881
|
+
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);
|
|
7676
7882
|
function ResourceTimelineChart({
|
|
7677
7883
|
resources,
|
|
7678
7884
|
dayWidth = DEFAULT_DAY_WIDTH,
|
|
7679
7885
|
rowHeaderWidth = DEFAULT_ROW_HEADER_WIDTH,
|
|
7680
7886
|
laneHeight = DEFAULT_LANE_HEIGHT,
|
|
7681
7887
|
headerHeight = DEFAULT_HEADER_HEIGHT,
|
|
7888
|
+
allowVerticalPan = false,
|
|
7889
|
+
customDays,
|
|
7890
|
+
isWeekend: isWeekend3,
|
|
7891
|
+
businessDays = true,
|
|
7682
7892
|
readonly,
|
|
7683
7893
|
disableResourceReassignment,
|
|
7684
7894
|
renderItem,
|
|
7685
7895
|
getItemClassName,
|
|
7896
|
+
onResourceItemClick,
|
|
7686
7897
|
onResourceItemMove
|
|
7687
7898
|
}) {
|
|
7688
7899
|
const scrollContainerRef = (0, import_react14.useRef)(null);
|
|
@@ -7696,9 +7907,18 @@ function ResourceTimelineChart({
|
|
|
7696
7907
|
const firstDay = dateRange[0] ?? /* @__PURE__ */ new Date();
|
|
7697
7908
|
return new Date(Date.UTC(firstDay.getUTCFullYear(), firstDay.getUTCMonth(), 1));
|
|
7698
7909
|
}, [dateRange]);
|
|
7910
|
+
const weekendPredicate = (0, import_react14.useMemo)(
|
|
7911
|
+
() => createCustomDayPredicate({ customDays, isWeekend: isWeekend3 }),
|
|
7912
|
+
[customDays, isWeekend3]
|
|
7913
|
+
);
|
|
7699
7914
|
const gridWidth = (0, import_react14.useMemo)(() => Math.round(dateRange.length * dayWidth), [dateRange.length, dayWidth]);
|
|
7700
7915
|
const layout = (0, import_react14.useMemo)(
|
|
7701
|
-
() => layoutResourceTimelineItems(resources, {
|
|
7916
|
+
() => layoutResourceTimelineItems(resources, {
|
|
7917
|
+
monthStart,
|
|
7918
|
+
dayWidth,
|
|
7919
|
+
laneHeight,
|
|
7920
|
+
rowGap: DEFAULT_RESOURCE_ROW_GAP
|
|
7921
|
+
}),
|
|
7702
7922
|
[resources, monthStart, dayWidth, laneHeight]
|
|
7703
7923
|
);
|
|
7704
7924
|
const todayInRange = (0, import_react14.useMemo)(() => {
|
|
@@ -7717,10 +7937,13 @@ function ResourceTimelineChart({
|
|
|
7717
7937
|
}, [layout.items]);
|
|
7718
7938
|
const { preview, startDrag } = useResourceItemDrag({
|
|
7719
7939
|
dayWidth,
|
|
7940
|
+
monthStart,
|
|
7720
7941
|
rows: layout.rows,
|
|
7721
7942
|
gridElementRef: gridRef,
|
|
7722
7943
|
readonly,
|
|
7723
7944
|
disableResourceReassignment,
|
|
7945
|
+
businessDays,
|
|
7946
|
+
weekendPredicate,
|
|
7724
7947
|
onResourceItemMove
|
|
7725
7948
|
});
|
|
7726
7949
|
const handlePanStart = (0, import_react14.useCallback)((event) => {
|
|
@@ -7759,7 +7982,9 @@ function ResourceTimelineChart({
|
|
|
7759
7982
|
return;
|
|
7760
7983
|
}
|
|
7761
7984
|
container.scrollLeft = pan.scrollX - (event.clientX - pan.startX);
|
|
7762
|
-
|
|
7985
|
+
if (allowVerticalPan) {
|
|
7986
|
+
container.scrollTop = pan.scrollY - (event.clientY - pan.startY);
|
|
7987
|
+
}
|
|
7763
7988
|
};
|
|
7764
7989
|
const handlePanEnd = () => {
|
|
7765
7990
|
if (!panStateRef.current?.active) {
|
|
@@ -7777,13 +8002,14 @@ function ResourceTimelineChart({
|
|
|
7777
8002
|
window.removeEventListener("mousemove", handlePanMove);
|
|
7778
8003
|
window.removeEventListener("mouseup", handlePanEnd);
|
|
7779
8004
|
};
|
|
7780
|
-
}, []);
|
|
8005
|
+
}, [allowVerticalPan]);
|
|
7781
8006
|
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "gantt-container gantt-resourceTimeline", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
7782
8007
|
"div",
|
|
7783
8008
|
{
|
|
7784
8009
|
ref: scrollContainerRef,
|
|
7785
8010
|
className: "gantt-resourceTimeline-scrollContainer",
|
|
7786
8011
|
style: { cursor: "grab" },
|
|
8012
|
+
"data-allow-vertical-pan": allowVerticalPan ? "true" : "false",
|
|
7787
8013
|
onMouseDown: handlePanStart,
|
|
7788
8014
|
children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "gantt-resourceTimeline-scrollContent", children: [
|
|
7789
8015
|
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
@@ -7799,13 +8025,26 @@ function ResourceTimelineChart({
|
|
|
7799
8025
|
style: { height: `${headerHeight}px` }
|
|
7800
8026
|
}
|
|
7801
8027
|
),
|
|
7802
|
-
layout.rows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime15.
|
|
8028
|
+
layout.rows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
7803
8029
|
"div",
|
|
7804
8030
|
{
|
|
7805
8031
|
className: "gantt-resourceTimeline-resourceHeader",
|
|
7806
8032
|
"data-resource-row-id": row.resourceId,
|
|
7807
|
-
style: {
|
|
7808
|
-
|
|
8033
|
+
style: {
|
|
8034
|
+
height: `${row.resourceRowHeight + DEFAULT_RESOURCE_ROW_GAP}px`,
|
|
8035
|
+
paddingBottom: `${DEFAULT_RESOURCE_ROW_GAP}px`
|
|
8036
|
+
},
|
|
8037
|
+
children: [
|
|
8038
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "gantt-resourceTimeline-resourceName", children: row.resource.name }),
|
|
8039
|
+
row.conflictCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
8040
|
+
"span",
|
|
8041
|
+
{
|
|
8042
|
+
className: "gantt-resourceTimeline-conflictBadge",
|
|
8043
|
+
"aria-label": `${row.conflictCount} \u043A\u043E\u043D\u0444\u043B\u0438\u043A\u0442\u043E\u0432`,
|
|
8044
|
+
children: row.conflictCount
|
|
8045
|
+
}
|
|
8046
|
+
)
|
|
8047
|
+
]
|
|
7809
8048
|
},
|
|
7810
8049
|
row.resourceId
|
|
7811
8050
|
))
|
|
@@ -7818,7 +8057,15 @@ function ResourceTimelineChart({
|
|
|
7818
8057
|
className: "gantt-resourceTimeline-chartSurface",
|
|
7819
8058
|
style: { minWidth: `${gridWidth}px` },
|
|
7820
8059
|
children: [
|
|
7821
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "gantt-resourceTimeline-stickyHeader", style: { width: `${gridWidth}px` }, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
8060
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "gantt-resourceTimeline-stickyHeader", style: { width: `${gridWidth}px` }, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
8061
|
+
TimeScaleHeader_default,
|
|
8062
|
+
{
|
|
8063
|
+
days: dateRange,
|
|
8064
|
+
dayWidth,
|
|
8065
|
+
headerHeight,
|
|
8066
|
+
isCustomWeekend: weekendPredicate
|
|
8067
|
+
}
|
|
8068
|
+
) }),
|
|
7822
8069
|
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
7823
8070
|
"div",
|
|
7824
8071
|
{
|
|
@@ -7826,7 +8073,15 @@ function ResourceTimelineChart({
|
|
|
7826
8073
|
className: "gantt-resourceTimeline-grid",
|
|
7827
8074
|
style: { width: `${gridWidth}px`, height: `${layout.totalHeight}px` },
|
|
7828
8075
|
children: [
|
|
7829
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
8076
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
8077
|
+
GridBackground_default,
|
|
8078
|
+
{
|
|
8079
|
+
dateRange,
|
|
8080
|
+
dayWidth,
|
|
8081
|
+
totalHeight: layout.totalHeight,
|
|
8082
|
+
isCustomWeekend: weekendPredicate
|
|
8083
|
+
}
|
|
8084
|
+
),
|
|
7830
8085
|
todayInRange && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TodayIndicator_default, { monthStart, dayWidth }),
|
|
7831
8086
|
layout.rows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
7832
8087
|
"div",
|
|
@@ -7835,7 +8090,7 @@ function ResourceTimelineChart({
|
|
|
7835
8090
|
"data-resource-row-id": row.resourceId,
|
|
7836
8091
|
style: {
|
|
7837
8092
|
top: `${row.resourceRowTop}px`,
|
|
7838
|
-
height: `${row.resourceRowHeight}px`
|
|
8093
|
+
height: `${row.resourceRowHeight + DEFAULT_RESOURCE_ROW_GAP}px`
|
|
7839
8094
|
}
|
|
7840
8095
|
},
|
|
7841
8096
|
row.resourceId
|
|
@@ -7843,17 +8098,18 @@ function ResourceTimelineChart({
|
|
|
7843
8098
|
Array.from(itemsByResourceId.values()).flatMap(
|
|
7844
8099
|
(resourceItems) => resourceItems.map((layoutItem) => {
|
|
7845
8100
|
const customClassName = getItemClassName?.(layoutItem.item);
|
|
8101
|
+
const isDraggingItem = preview?.itemId === layoutItem.itemId;
|
|
7846
8102
|
const className = [
|
|
7847
8103
|
"gantt-resourceTimeline-item",
|
|
7848
|
-
|
|
8104
|
+
isDraggingItem && "gantt-resourceTimeline-itemDragging",
|
|
7849
8105
|
(readonly || layoutItem.item.locked) && "gantt-resourceTimeline-itemDisabled",
|
|
7850
8106
|
customClassName
|
|
7851
8107
|
].filter(Boolean).join(" ");
|
|
7852
8108
|
const laneCount = Math.max(1, Math.round(layoutItem.resourceRowHeight / layoutItem.height));
|
|
7853
|
-
const previewStyle =
|
|
8109
|
+
const previewStyle = isDraggingItem ? getVisualItemGeometry({
|
|
7854
8110
|
left: preview.left,
|
|
7855
8111
|
top: preview.top,
|
|
7856
|
-
width:
|
|
8112
|
+
width: preview.width,
|
|
7857
8113
|
height: layoutItem.height
|
|
7858
8114
|
}, layoutItem.laneIndex, laneCount) : void 0;
|
|
7859
8115
|
const itemGeometry = getVisualItemGeometry({
|
|
@@ -7862,25 +8118,96 @@ function ResourceTimelineChart({
|
|
|
7862
8118
|
width: layoutItem.width,
|
|
7863
8119
|
height: layoutItem.height
|
|
7864
8120
|
}, layoutItem.laneIndex, laneCount);
|
|
7865
|
-
|
|
8121
|
+
const overlayStartDate = isDraggingItem ? preview.startDate : layoutItem.startDate;
|
|
8122
|
+
const overlayEndDate = isDraggingItem ? preview.endDate : layoutItem.endDate;
|
|
8123
|
+
const weekendOverlaySegments = businessDays ? getWeekendOverlaySegments(overlayStartDate, overlayEndDate, dayWidth, weekendPredicate) : [];
|
|
8124
|
+
const conflictOverlaySegments = getRangeOverlaySegments(
|
|
8125
|
+
overlayStartDate,
|
|
8126
|
+
isDraggingItem ? [] : layoutItem.conflictRanges,
|
|
8127
|
+
dayWidth
|
|
8128
|
+
);
|
|
8129
|
+
const durationValue = getDurationValue(
|
|
8130
|
+
overlayStartDate,
|
|
8131
|
+
overlayEndDate,
|
|
8132
|
+
businessDays,
|
|
8133
|
+
weekendPredicate
|
|
8134
|
+
);
|
|
8135
|
+
const renderContext = {
|
|
8136
|
+
startDate: overlayStartDate,
|
|
8137
|
+
endDate: overlayEndDate,
|
|
8138
|
+
durationDays: durationValue,
|
|
8139
|
+
isDragging: isDraggingItem
|
|
8140
|
+
};
|
|
8141
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
7866
8142
|
"div",
|
|
7867
8143
|
{
|
|
7868
8144
|
className,
|
|
7869
8145
|
"data-resource-item-id": layoutItem.itemId,
|
|
7870
8146
|
onMouseDown: (event) => startDrag(event, layoutItem),
|
|
8147
|
+
onClick: () => onResourceItemClick?.(layoutItem.item),
|
|
8148
|
+
onKeyDown: (event) => {
|
|
8149
|
+
if (!onResourceItemClick) {
|
|
8150
|
+
return;
|
|
8151
|
+
}
|
|
8152
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
8153
|
+
event.preventDefault();
|
|
8154
|
+
onResourceItemClick(layoutItem.item);
|
|
8155
|
+
}
|
|
8156
|
+
},
|
|
8157
|
+
role: onResourceItemClick ? "button" : void 0,
|
|
8158
|
+
tabIndex: onResourceItemClick ? 0 : void 0,
|
|
7871
8159
|
style: {
|
|
7872
8160
|
left: `${itemGeometry.left}px`,
|
|
7873
8161
|
top: `${itemGeometry.top}px`,
|
|
7874
|
-
...previewStyle,
|
|
7875
8162
|
width: `${itemGeometry.width}px`,
|
|
7876
8163
|
height: `${itemGeometry.height}px`,
|
|
8164
|
+
...previewStyle,
|
|
7877
8165
|
backgroundColor: layoutItem.item.color ?? "var(--gantt-task-bar-default-color, #3b82f6)"
|
|
7878
8166
|
},
|
|
7879
|
-
children:
|
|
7880
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.
|
|
7881
|
-
|
|
7882
|
-
|
|
7883
|
-
|
|
8167
|
+
children: [
|
|
8168
|
+
!readonly && !layoutItem.item.locked && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
|
|
8169
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "gantt-resourceTimeline-resizeHandle gantt-resourceTimeline-resizeHandleStart" }),
|
|
8170
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "gantt-resourceTimeline-resizeHandle gantt-resourceTimeline-resizeHandleEnd" })
|
|
8171
|
+
] }),
|
|
8172
|
+
weekendOverlaySegments.map((segment, index) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
8173
|
+
"span",
|
|
8174
|
+
{
|
|
8175
|
+
className: "gantt-resourceTimeline-weekendOverlay",
|
|
8176
|
+
"data-resource-weekend-overlay": "true",
|
|
8177
|
+
style: {
|
|
8178
|
+
left: `${segment.left}px`,
|
|
8179
|
+
width: `${segment.width}px`
|
|
8180
|
+
}
|
|
8181
|
+
},
|
|
8182
|
+
`weekend-overlay-${index}`
|
|
8183
|
+
)),
|
|
8184
|
+
conflictOverlaySegments.map((segment, index) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
8185
|
+
"span",
|
|
8186
|
+
{
|
|
8187
|
+
className: "gantt-resourceTimeline-conflictOverlay",
|
|
8188
|
+
"data-resource-conflict-overlay": "true",
|
|
8189
|
+
style: {
|
|
8190
|
+
left: `${segment.left}px`,
|
|
8191
|
+
width: `${segment.width}px`
|
|
8192
|
+
}
|
|
8193
|
+
},
|
|
8194
|
+
`conflict-overlay-${index}`
|
|
8195
|
+
)),
|
|
8196
|
+
/* @__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: [
|
|
8197
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "gantt-resourceTimeline-defaultItemMain", children: [
|
|
8198
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
8199
|
+
"span",
|
|
8200
|
+
{
|
|
8201
|
+
className: "gantt-resourceTimeline-itemDurationChip",
|
|
8202
|
+
"aria-label": `${durationValue} \u0434`,
|
|
8203
|
+
children: durationValue
|
|
8204
|
+
}
|
|
8205
|
+
),
|
|
8206
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "gantt-resourceTimeline-itemTitle", children: layoutItem.item.title })
|
|
8207
|
+
] }),
|
|
8208
|
+
layoutItem.item.subtitle && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "gantt-resourceTimeline-itemSubtitle", children: layoutItem.item.subtitle })
|
|
8209
|
+
] }) })
|
|
8210
|
+
]
|
|
7884
8211
|
},
|
|
7885
8212
|
layoutItem.itemId
|
|
7886
8213
|
);
|