gantt-lib 0.74.0 → 0.75.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -515,6 +515,7 @@ __export(index_exports, {
515
515
  Popover: () => Popover,
516
516
  PopoverContent: () => PopoverContent,
517
517
  PopoverTrigger: () => PopoverTrigger,
518
+ ResourceTimelineChart: () => ResourceTimelineChart,
518
519
  TaskList: () => TaskList,
519
520
  TaskRow: () => TaskRow_default,
520
521
  TimeScaleHeader: () => TimeScaleHeader_default,
@@ -578,6 +579,7 @@ __export(index_exports, {
578
579
  isTaskParent: () => isTaskParent,
579
580
  isToday: () => isToday,
580
581
  isWeekend: () => isWeekend,
582
+ layoutResourceTimelineItems: () => layoutResourceTimelineItems,
581
583
  moveTaskRange: () => moveTaskRange,
582
584
  moveTaskWithCascade: () => moveTaskWithCascade,
583
585
  nameContains: () => nameContains,
@@ -610,7 +612,7 @@ __export(index_exports, {
610
612
  module.exports = __toCommonJS(index_exports);
611
613
 
612
614
  // src/components/GanttChart/GanttChart.tsx
613
- var import_react13 = require("react");
615
+ var import_react15 = require("react");
614
616
  init_dateUtils();
615
617
 
616
618
  // src/core/scheduling/index.ts
@@ -7357,6 +7359,522 @@ var TaskList = ({
7357
7359
  );
7358
7360
  };
7359
7361
 
7362
+ // src/components/ResourceTimelineChart/ResourceTimelineChart.tsx
7363
+ var import_react14 = require("react");
7364
+ init_dateUtils();
7365
+
7366
+ // src/utils/resourceTimelineLayout.ts
7367
+ init_dateUtils();
7368
+ var isInvalidDate = (date) => Number.isNaN(date.getTime());
7369
+ var getUTCDayNumber = (date) => {
7370
+ return Math.floor(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()) / 864e5);
7371
+ };
7372
+ var compareParsedItems = (a, b) => {
7373
+ const startDiff = getUTCDayNumber(a.startDate) - getUTCDayNumber(b.startDate);
7374
+ if (startDiff !== 0) {
7375
+ return startDiff;
7376
+ }
7377
+ const endDiff = getUTCDayNumber(a.endDate) - getUTCDayNumber(b.endDate);
7378
+ if (endDiff !== 0) {
7379
+ return endDiff;
7380
+ }
7381
+ return a.item.id.localeCompare(b.item.id);
7382
+ };
7383
+ var layoutResourceTimelineItems = (resources, options) => {
7384
+ const rows = [];
7385
+ const items = [];
7386
+ const diagnostics = [];
7387
+ let currentTop = 0;
7388
+ for (const resource of resources) {
7389
+ const parsedItems = [];
7390
+ for (const item of resource.items) {
7391
+ try {
7392
+ const startDate = parseUTCDate(item.startDate);
7393
+ const endDate = parseUTCDate(item.endDate);
7394
+ if (isInvalidDate(startDate) || isInvalidDate(endDate)) {
7395
+ throw new Error("Invalid date");
7396
+ }
7397
+ parsedItems.push({ item, startDate, endDate });
7398
+ } catch {
7399
+ diagnostics.push({
7400
+ itemId: item.id,
7401
+ resourceId: resource.id,
7402
+ reason: "invalid-date"
7403
+ });
7404
+ }
7405
+ }
7406
+ parsedItems.sort(compareParsedItems);
7407
+ const laneEndDays = [];
7408
+ const laidOutItems = [];
7409
+ for (const parsed of parsedItems) {
7410
+ const startDay = getUTCDayNumber(parsed.startDate);
7411
+ const endDay = getUTCDayNumber(parsed.endDate);
7412
+ let laneIndex = laneEndDays.findIndex((laneEndDay) => laneEndDay < startDay);
7413
+ if (laneIndex === -1) {
7414
+ laneIndex = laneEndDays.length;
7415
+ laneEndDays.push(endDay);
7416
+ } else {
7417
+ laneEndDays[laneIndex] = endDay;
7418
+ }
7419
+ const { left, width } = calculateTaskBar(parsed.startDate, parsed.endDate, options.monthStart, options.dayWidth);
7420
+ laidOutItems.push({
7421
+ item: parsed.item,
7422
+ itemId: parsed.item.id,
7423
+ resourceId: resource.id,
7424
+ laneIndex,
7425
+ left,
7426
+ width,
7427
+ resourceRowTop: currentTop,
7428
+ resourceRowHeight: 0,
7429
+ top: currentTop + laneIndex * options.laneHeight,
7430
+ height: options.laneHeight,
7431
+ startDate: parsed.startDate,
7432
+ endDate: parsed.endDate
7433
+ });
7434
+ }
7435
+ const laneCount = Math.max(1, laneEndDays.length);
7436
+ const resourceRowHeight = laneCount * options.laneHeight;
7437
+ const row = {
7438
+ resource,
7439
+ resourceId: resource.id,
7440
+ laneCount,
7441
+ resourceRowTop: currentTop,
7442
+ resourceRowHeight
7443
+ };
7444
+ rows.push(row);
7445
+ items.push(...laidOutItems.map((item) => ({
7446
+ ...item,
7447
+ resourceRowHeight
7448
+ })));
7449
+ currentTop += resourceRowHeight;
7450
+ }
7451
+ return {
7452
+ rows,
7453
+ items,
7454
+ diagnostics,
7455
+ totalHeight: currentTop
7456
+ };
7457
+ };
7458
+
7459
+ // src/hooks/useResourceItemDrag.ts
7460
+ var import_react13 = require("react");
7461
+ var snapToDay = (pixels, dayWidth) => {
7462
+ return Math.round(pixels / dayWidth) * dayWidth;
7463
+ };
7464
+ var addUTCDays = (date, days) => {
7465
+ return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate() + days));
7466
+ };
7467
+ var resolveTargetResource = (rows, clientY, gridTop) => {
7468
+ const localY = clientY - gridTop;
7469
+ return rows.find(
7470
+ (row) => localY >= row.resourceRowTop && localY < row.resourceRowTop + row.resourceRowHeight
7471
+ )?.resource ?? null;
7472
+ };
7473
+ var useResourceItemDrag = ({
7474
+ dayWidth,
7475
+ rows,
7476
+ gridElementRef,
7477
+ readonly,
7478
+ disableResourceReassignment,
7479
+ onResourceItemMove
7480
+ }) => {
7481
+ const activeDragRef = (0, import_react13.useRef)(null);
7482
+ const rowsRef = (0, import_react13.useRef)(rows);
7483
+ const onResourceItemMoveRef = (0, import_react13.useRef)(onResourceItemMove);
7484
+ const rafRef = (0, import_react13.useRef)(null);
7485
+ const [preview, setPreview] = (0, import_react13.useState)(null);
7486
+ (0, import_react13.useEffect)(() => {
7487
+ rowsRef.current = rows;
7488
+ }, [rows]);
7489
+ (0, import_react13.useEffect)(() => {
7490
+ onResourceItemMoveRef.current = onResourceItemMove;
7491
+ }, [onResourceItemMove]);
7492
+ const clearRaf = (0, import_react13.useCallback)(() => {
7493
+ if (rafRef.current !== null) {
7494
+ cancelAnimationFrame(rafRef.current);
7495
+ rafRef.current = null;
7496
+ }
7497
+ }, []);
7498
+ const cancelDrag2 = (0, import_react13.useCallback)(() => {
7499
+ clearRaf();
7500
+ activeDragRef.current = null;
7501
+ setPreview(null);
7502
+ }, [clearRaf]);
7503
+ (0, import_react13.useEffect)(() => {
7504
+ const handleMouseMove = (event) => {
7505
+ const activeDrag = activeDragRef.current;
7506
+ if (!activeDrag || rafRef.current !== null) {
7507
+ return;
7508
+ }
7509
+ rafRef.current = requestAnimationFrame(() => {
7510
+ rafRef.current = null;
7511
+ const latestDrag = activeDragRef.current;
7512
+ if (!latestDrag) {
7513
+ return;
7514
+ }
7515
+ const nextLeft = latestDrag.initialLeft + snapToDay(event.clientX - latestDrag.startX, latestDrag.dayWidth);
7516
+ const nextTop = disableResourceReassignment ? latestDrag.initialTop : latestDrag.initialTop + (event.clientY - latestDrag.startY);
7517
+ latestDrag.currentLeft = nextLeft;
7518
+ latestDrag.currentTop = nextTop;
7519
+ setPreview({
7520
+ itemId: latestDrag.itemId,
7521
+ left: nextLeft,
7522
+ top: nextTop
7523
+ });
7524
+ });
7525
+ };
7526
+ const handleMouseUp = (event) => {
7527
+ const activeDrag = activeDragRef.current;
7528
+ if (!activeDrag) {
7529
+ return;
7530
+ }
7531
+ clearRaf();
7532
+ activeDragRef.current = null;
7533
+ setPreview(null);
7534
+ const gridTop = gridElementRef?.current?.getBoundingClientRect().top ?? 0;
7535
+ const targetResource = disableResourceReassignment ? rowsRef.current.find((row) => row.resourceId === activeDrag.fromResourceId)?.resource ?? null : resolveTargetResource(rowsRef.current, event.clientY, gridTop);
7536
+ if (!targetResource) {
7537
+ return;
7538
+ }
7539
+ const dayDelta = Math.round((activeDrag.currentLeft - activeDrag.initialLeft) / activeDrag.dayWidth);
7540
+ onResourceItemMoveRef.current?.({
7541
+ item: activeDrag.item,
7542
+ itemId: activeDrag.itemId,
7543
+ fromResourceId: activeDrag.fromResourceId,
7544
+ toResourceId: targetResource.id,
7545
+ startDate: addUTCDays(activeDrag.startDate, dayDelta),
7546
+ endDate: addUTCDays(activeDrag.endDate, dayDelta)
7547
+ });
7548
+ };
7549
+ window.addEventListener("mousemove", handleMouseMove);
7550
+ window.addEventListener("mouseup", handleMouseUp);
7551
+ return () => {
7552
+ window.removeEventListener("mousemove", handleMouseMove);
7553
+ window.removeEventListener("mouseup", handleMouseUp);
7554
+ cancelDrag2();
7555
+ };
7556
+ }, [cancelDrag2, clearRaf, disableResourceReassignment, gridElementRef]);
7557
+ const startDrag = (0, import_react13.useCallback)((event, layoutItem) => {
7558
+ if (readonly || layoutItem.item.locked || event.button !== 0) {
7559
+ return;
7560
+ }
7561
+ event.preventDefault();
7562
+ activeDragRef.current = {
7563
+ item: layoutItem.item,
7564
+ itemId: layoutItem.itemId,
7565
+ fromResourceId: layoutItem.resourceId,
7566
+ startX: event.clientX,
7567
+ startY: event.clientY,
7568
+ initialLeft: layoutItem.left,
7569
+ initialTop: layoutItem.top,
7570
+ currentLeft: layoutItem.left,
7571
+ currentTop: layoutItem.top,
7572
+ dayWidth,
7573
+ startDate: layoutItem.startDate,
7574
+ endDate: layoutItem.endDate
7575
+ };
7576
+ setPreview({
7577
+ itemId: layoutItem.itemId,
7578
+ left: layoutItem.left,
7579
+ top: layoutItem.top
7580
+ });
7581
+ }, [dayWidth, readonly]);
7582
+ return {
7583
+ preview,
7584
+ startDrag,
7585
+ cancelDrag: cancelDrag2
7586
+ };
7587
+ };
7588
+
7589
+ // src/components/ResourceTimelineChart/ResourceTimelineChart.tsx
7590
+ var import_jsx_runtime15 = require("react/jsx-runtime");
7591
+ var DEFAULT_DAY_WIDTH = 40;
7592
+ var DEFAULT_HEADER_HEIGHT = 40;
7593
+ var DEFAULT_LANE_HEIGHT = 40;
7594
+ var DEFAULT_ROW_HEADER_WIDTH = 240;
7595
+ var ITEM_OUTER_VERTICAL_INSET = 2;
7596
+ var ITEM_INNER_VERTICAL_INSET = 1;
7597
+ var ITEM_HORIZONTAL_INSET = 1;
7598
+ var isValidDate = (date) => !Number.isNaN(date.getTime());
7599
+ var getResourceTimelineDays = (items) => {
7600
+ if (items.length === 0) {
7601
+ return getMonthDays(/* @__PURE__ */ new Date());
7602
+ }
7603
+ let minDate = null;
7604
+ let maxDate = null;
7605
+ for (const item of items) {
7606
+ const startDate = parseUTCDate(item.startDate);
7607
+ const endDate = parseUTCDate(item.endDate);
7608
+ if (!minDate || startDate.getTime() < minDate.getTime()) {
7609
+ minDate = startDate;
7610
+ }
7611
+ if (!maxDate || endDate.getTime() > maxDate.getTime()) {
7612
+ maxDate = endDate;
7613
+ }
7614
+ }
7615
+ if (!minDate || !maxDate) {
7616
+ return getMonthDays(/* @__PURE__ */ new Date());
7617
+ }
7618
+ const startOfMonth2 = new Date(Date.UTC(minDate.getUTCFullYear(), minDate.getUTCMonth(), 1));
7619
+ const endOfMonth = new Date(Date.UTC(maxDate.getUTCFullYear(), maxDate.getUTCMonth() + 1, 0));
7620
+ const days = [];
7621
+ const current = new Date(startOfMonth2);
7622
+ while (current.getTime() <= endOfMonth.getTime()) {
7623
+ days.push(new Date(Date.UTC(current.getUTCFullYear(), current.getUTCMonth(), current.getUTCDate())));
7624
+ current.setUTCDate(current.getUTCDate() + 1);
7625
+ }
7626
+ return days;
7627
+ };
7628
+ var collectValidItems = (resources) => {
7629
+ return resources.flatMap(
7630
+ (resource) => resource.items.flatMap((item) => {
7631
+ try {
7632
+ const startDate = parseUTCDate(item.startDate);
7633
+ const endDate = parseUTCDate(item.endDate);
7634
+ if (!isValidDate(startDate) || !isValidDate(endDate)) {
7635
+ return [];
7636
+ }
7637
+ return [{ startDate, endDate }];
7638
+ } catch {
7639
+ return [];
7640
+ }
7641
+ })
7642
+ );
7643
+ };
7644
+ var getVisualItemGeometry = (geometry, laneIndex, laneCount) => {
7645
+ const topInset = laneIndex === 0 ? ITEM_OUTER_VERTICAL_INSET : ITEM_INNER_VERTICAL_INSET;
7646
+ const bottomInset = laneIndex === laneCount - 1 ? ITEM_OUTER_VERTICAL_INSET : ITEM_INNER_VERTICAL_INSET;
7647
+ return {
7648
+ left: geometry.left + ITEM_HORIZONTAL_INSET,
7649
+ top: geometry.top + topInset,
7650
+ width: Math.max(0, geometry.width - ITEM_HORIZONTAL_INSET * 2),
7651
+ height: Math.max(0, geometry.height - topInset - bottomInset)
7652
+ };
7653
+ };
7654
+ function ResourceTimelineChart({
7655
+ resources,
7656
+ dayWidth = DEFAULT_DAY_WIDTH,
7657
+ rowHeaderWidth = DEFAULT_ROW_HEADER_WIDTH,
7658
+ laneHeight = DEFAULT_LANE_HEIGHT,
7659
+ headerHeight = DEFAULT_HEADER_HEIGHT,
7660
+ readonly,
7661
+ disableResourceReassignment,
7662
+ renderItem,
7663
+ getItemClassName,
7664
+ onResourceItemMove
7665
+ }) {
7666
+ const scrollContainerRef = (0, import_react14.useRef)(null);
7667
+ const gridRef = (0, import_react14.useRef)(null);
7668
+ const panStateRef = (0, import_react14.useRef)(null);
7669
+ const validItems = (0, import_react14.useMemo)(() => collectValidItems(resources), [resources]);
7670
+ const dateRange = (0, import_react14.useMemo)(() => {
7671
+ return getResourceTimelineDays(validItems);
7672
+ }, [validItems]);
7673
+ const monthStart = (0, import_react14.useMemo)(() => {
7674
+ const firstDay = dateRange[0] ?? /* @__PURE__ */ new Date();
7675
+ return new Date(Date.UTC(firstDay.getUTCFullYear(), firstDay.getUTCMonth(), 1));
7676
+ }, [dateRange]);
7677
+ const gridWidth = (0, import_react14.useMemo)(() => Math.round(dateRange.length * dayWidth), [dateRange.length, dayWidth]);
7678
+ const layout = (0, import_react14.useMemo)(
7679
+ () => layoutResourceTimelineItems(resources, { monthStart, dayWidth, laneHeight }),
7680
+ [resources, monthStart, dayWidth, laneHeight]
7681
+ );
7682
+ const todayInRange = (0, import_react14.useMemo)(() => {
7683
+ const now = /* @__PURE__ */ new Date();
7684
+ const today = new Date(Date.UTC(now.getFullYear(), now.getMonth(), now.getDate()));
7685
+ return dateRange.some((day) => day.getTime() === today.getTime());
7686
+ }, [dateRange]);
7687
+ const itemsByResourceId = (0, import_react14.useMemo)(() => {
7688
+ const map = /* @__PURE__ */ new Map();
7689
+ for (const item of layout.items) {
7690
+ const next = map.get(item.resourceId) ?? [];
7691
+ next.push(item);
7692
+ map.set(item.resourceId, next);
7693
+ }
7694
+ return map;
7695
+ }, [layout.items]);
7696
+ const { preview, startDrag } = useResourceItemDrag({
7697
+ dayWidth,
7698
+ rows: layout.rows,
7699
+ gridElementRef: gridRef,
7700
+ readonly,
7701
+ disableResourceReassignment,
7702
+ onResourceItemMove
7703
+ });
7704
+ const handlePanStart = (0, import_react14.useCallback)((event) => {
7705
+ if (event.button !== 0) {
7706
+ return;
7707
+ }
7708
+ const target = event.target;
7709
+ if (target.closest("[data-resource-item-id]")) {
7710
+ return;
7711
+ }
7712
+ if (target.closest("input, button, textarea, [contenteditable]")) {
7713
+ return;
7714
+ }
7715
+ const container = scrollContainerRef.current;
7716
+ if (!container) {
7717
+ return;
7718
+ }
7719
+ panStateRef.current = {
7720
+ active: true,
7721
+ startX: event.clientX,
7722
+ startY: event.clientY,
7723
+ scrollX: container.scrollLeft,
7724
+ scrollY: container.scrollTop
7725
+ };
7726
+ if (document.activeElement instanceof HTMLElement) {
7727
+ document.activeElement.blur();
7728
+ }
7729
+ container.style.cursor = "grabbing";
7730
+ event.preventDefault();
7731
+ }, []);
7732
+ (0, import_react14.useEffect)(() => {
7733
+ const handlePanMove = (event) => {
7734
+ const pan = panStateRef.current;
7735
+ const container = scrollContainerRef.current;
7736
+ if (!pan?.active || !container) {
7737
+ return;
7738
+ }
7739
+ container.scrollLeft = pan.scrollX - (event.clientX - pan.startX);
7740
+ container.scrollTop = pan.scrollY - (event.clientY - pan.startY);
7741
+ };
7742
+ const handlePanEnd = () => {
7743
+ if (!panStateRef.current?.active) {
7744
+ return;
7745
+ }
7746
+ panStateRef.current = null;
7747
+ const container = scrollContainerRef.current;
7748
+ if (container) {
7749
+ container.style.cursor = "";
7750
+ }
7751
+ };
7752
+ window.addEventListener("mousemove", handlePanMove);
7753
+ window.addEventListener("mouseup", handlePanEnd);
7754
+ return () => {
7755
+ window.removeEventListener("mousemove", handlePanMove);
7756
+ window.removeEventListener("mouseup", handlePanEnd);
7757
+ };
7758
+ }, []);
7759
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "gantt-container gantt-resourceTimeline", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
7760
+ "div",
7761
+ {
7762
+ ref: scrollContainerRef,
7763
+ className: "gantt-resourceTimeline-scrollContainer",
7764
+ style: { cursor: "grab" },
7765
+ onMouseDown: handlePanStart,
7766
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "gantt-resourceTimeline-scrollContent", children: [
7767
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
7768
+ "div",
7769
+ {
7770
+ className: "gantt-resourceTimeline-resourceColumn",
7771
+ style: { width: `${rowHeaderWidth}px`, minWidth: `${rowHeaderWidth}px` },
7772
+ children: [
7773
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
7774
+ "div",
7775
+ {
7776
+ className: "gantt-resourceTimeline-corner",
7777
+ style: { height: `${headerHeight}px` }
7778
+ }
7779
+ ),
7780
+ layout.rows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
7781
+ "div",
7782
+ {
7783
+ className: "gantt-resourceTimeline-resourceHeader",
7784
+ "data-resource-row-id": row.resourceId,
7785
+ style: { height: `${row.resourceRowHeight}px` },
7786
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "gantt-resourceTimeline-resourceName", children: row.resource.name })
7787
+ },
7788
+ row.resourceId
7789
+ ))
7790
+ ]
7791
+ }
7792
+ ),
7793
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
7794
+ "div",
7795
+ {
7796
+ className: "gantt-resourceTimeline-chartSurface",
7797
+ style: { minWidth: `${gridWidth}px` },
7798
+ children: [
7799
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "gantt-resourceTimeline-stickyHeader", style: { width: `${gridWidth}px` }, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TimeScaleHeader_default, { days: dateRange, dayWidth, headerHeight }) }),
7800
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
7801
+ "div",
7802
+ {
7803
+ ref: gridRef,
7804
+ className: "gantt-resourceTimeline-grid",
7805
+ style: { width: `${gridWidth}px`, height: `${layout.totalHeight}px` },
7806
+ children: [
7807
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(GridBackground_default, { dateRange, dayWidth, totalHeight: layout.totalHeight }),
7808
+ todayInRange && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TodayIndicator_default, { monthStart, dayWidth }),
7809
+ layout.rows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
7810
+ "div",
7811
+ {
7812
+ className: "gantt-resourceTimeline-row",
7813
+ "data-resource-row-id": row.resourceId,
7814
+ style: {
7815
+ top: `${row.resourceRowTop}px`,
7816
+ height: `${row.resourceRowHeight}px`
7817
+ }
7818
+ },
7819
+ row.resourceId
7820
+ )),
7821
+ Array.from(itemsByResourceId.values()).flatMap(
7822
+ (resourceItems) => resourceItems.map((layoutItem) => {
7823
+ const customClassName = getItemClassName?.(layoutItem.item);
7824
+ const className = [
7825
+ "gantt-resourceTimeline-item",
7826
+ preview?.itemId === layoutItem.itemId && "gantt-resourceTimeline-itemDragging",
7827
+ (readonly || layoutItem.item.locked) && "gantt-resourceTimeline-itemDisabled",
7828
+ customClassName
7829
+ ].filter(Boolean).join(" ");
7830
+ const laneCount = Math.max(1, Math.round(layoutItem.resourceRowHeight / layoutItem.height));
7831
+ const previewStyle = preview?.itemId === layoutItem.itemId ? getVisualItemGeometry({
7832
+ left: preview.left,
7833
+ top: preview.top,
7834
+ width: layoutItem.width,
7835
+ height: layoutItem.height
7836
+ }, layoutItem.laneIndex, laneCount) : void 0;
7837
+ const itemGeometry = getVisualItemGeometry({
7838
+ left: layoutItem.left,
7839
+ top: layoutItem.top,
7840
+ width: layoutItem.width,
7841
+ height: layoutItem.height
7842
+ }, layoutItem.laneIndex, laneCount);
7843
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
7844
+ "div",
7845
+ {
7846
+ className,
7847
+ "data-resource-item-id": layoutItem.itemId,
7848
+ onMouseDown: (event) => startDrag(event, layoutItem),
7849
+ style: {
7850
+ left: `${itemGeometry.left}px`,
7851
+ top: `${itemGeometry.top}px`,
7852
+ ...previewStyle,
7853
+ width: `${itemGeometry.width}px`,
7854
+ height: `${itemGeometry.height}px`,
7855
+ backgroundColor: layoutItem.item.color ?? "var(--gantt-task-bar-default-color, #3b82f6)"
7856
+ },
7857
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "gantt-resourceTimeline-itemInner", children: renderItem ? renderItem(layoutItem.item) : /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
7858
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "gantt-resourceTimeline-itemTitle", children: layoutItem.item.title }),
7859
+ layoutItem.item.subtitle && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "gantt-resourceTimeline-itemSubtitle", children: layoutItem.item.subtitle }),
7860
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "gantt-resourceTimeline-itemDates", children: formatDateRangeLabel(layoutItem.startDate, layoutItem.endDate) })
7861
+ ] }) })
7862
+ },
7863
+ layoutItem.itemId
7864
+ );
7865
+ })
7866
+ )
7867
+ ]
7868
+ }
7869
+ )
7870
+ ]
7871
+ }
7872
+ )
7873
+ ] })
7874
+ }
7875
+ ) });
7876
+ }
7877
+
7360
7878
  // src/components/GanttChart/print.ts
7361
7879
  function getPrintDocumentTitle({
7362
7880
  header,
@@ -7695,9 +8213,21 @@ async function printGanttChart({
7695
8213
  }
7696
8214
 
7697
8215
  // src/components/GanttChart/GanttChart.tsx
7698
- var import_jsx_runtime15 = require("react/jsx-runtime");
8216
+ var import_jsx_runtime16 = require("react/jsx-runtime");
7699
8217
  var SCROLL_TO_ROW_CONTEXT_ROWS = 2;
7700
8218
  function GanttChartInner(props, ref) {
8219
+ if (props.mode === "resource-planner") {
8220
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ResourceTimelineChart, { ...props });
8221
+ }
8222
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8223
+ TaskGanttChart,
8224
+ {
8225
+ ...props,
8226
+ ref
8227
+ }
8228
+ );
8229
+ }
8230
+ function TaskGanttChartInner(props, ref) {
7701
8231
  const {
7702
8232
  tasks,
7703
8233
  dayWidth = 40,
@@ -7737,28 +8267,28 @@ function GanttChartInner(props, ref) {
7737
8267
  additionalColumns,
7738
8268
  taskListMenuCommands
7739
8269
  } = props;
7740
- const containerRef = (0, import_react13.useRef)(null);
7741
- const scrollContainerRef = (0, import_react13.useRef)(null);
7742
- const scrollContentRef = (0, import_react13.useRef)(null);
7743
- const [selectedTaskId, setSelectedTaskId] = (0, import_react13.useState)(null);
7744
- const [taskListHasRightShadow, setTaskListHasRightShadow] = (0, import_react13.useState)(false);
7745
- const [selectedChip, setSelectedChip] = (0, import_react13.useState)(null);
7746
- const [internalCollapsedParentIds, setInternalCollapsedParentIds] = (0, import_react13.useState)(/* @__PURE__ */ new Set());
8270
+ const containerRef = (0, import_react15.useRef)(null);
8271
+ const scrollContainerRef = (0, import_react15.useRef)(null);
8272
+ const scrollContentRef = (0, import_react15.useRef)(null);
8273
+ const [selectedTaskId, setSelectedTaskId] = (0, import_react15.useState)(null);
8274
+ const [taskListHasRightShadow, setTaskListHasRightShadow] = (0, import_react15.useState)(false);
8275
+ const [selectedChip, setSelectedChip] = (0, import_react15.useState)(null);
8276
+ const [internalCollapsedParentIds, setInternalCollapsedParentIds] = (0, import_react15.useState)(/* @__PURE__ */ new Set());
7747
8277
  const collapsedParentIds = externalCollapsedParentIds ?? internalCollapsedParentIds;
7748
- const [editingTaskId, setEditingTaskId] = (0, import_react13.useState)(null);
7749
- const normalizedTasks = (0, import_react13.useMemo)(() => normalizeHierarchyTasks(tasks), [tasks]);
7750
- const isCustomWeekend = (0, import_react13.useMemo)(
8278
+ const [editingTaskId, setEditingTaskId] = (0, import_react15.useState)(null);
8279
+ const normalizedTasks = (0, import_react15.useMemo)(() => normalizeHierarchyTasks(tasks), [tasks]);
8280
+ const isCustomWeekend = (0, import_react15.useMemo)(
7751
8281
  () => createCustomDayPredicate({ customDays, isWeekend: isWeekend3 }),
7752
8282
  [customDays, isWeekend3]
7753
8283
  );
7754
- const dateRange = (0, import_react13.useMemo)(() => getMultiMonthDays(normalizedTasks), [normalizedTasks]);
7755
- const [validationResult, setValidationResult] = (0, import_react13.useState)(null);
7756
- const [cascadeOverrides, setCascadeOverrides] = (0, import_react13.useState)(/* @__PURE__ */ new Map());
7757
- const gridWidth = (0, import_react13.useMemo)(
8284
+ const dateRange = (0, import_react15.useMemo)(() => getMultiMonthDays(normalizedTasks), [normalizedTasks]);
8285
+ const [validationResult, setValidationResult] = (0, import_react15.useState)(null);
8286
+ const [cascadeOverrides, setCascadeOverrides] = (0, import_react15.useState)(/* @__PURE__ */ new Map());
8287
+ const gridWidth = (0, import_react15.useMemo)(
7758
8288
  () => Math.round(dateRange.length * dayWidth),
7759
8289
  [dateRange.length, dayWidth]
7760
8290
  );
7761
- const visibleTasks = (0, import_react13.useMemo)(() => {
8291
+ const visibleTasks = (0, import_react15.useMemo)(() => {
7762
8292
  const parentMap = new Map(normalizedTasks.map((t) => [t.id, t.parentId]));
7763
8293
  function isAnyAncestorCollapsed(parentId) {
7764
8294
  let current = parentId;
@@ -7774,11 +8304,11 @@ function GanttChartInner(props, ref) {
7774
8304
  }
7775
8305
  return tasks2;
7776
8306
  }, [normalizedTasks, collapsedParentIds, filterMode, taskFilter]);
7777
- const matchedTaskIds = (0, import_react13.useMemo)(() => {
8307
+ const matchedTaskIds = (0, import_react15.useMemo)(() => {
7778
8308
  if (!taskFilter) return /* @__PURE__ */ new Set();
7779
8309
  return new Set(visibleTasks.filter(taskFilter).map((task) => task.id));
7780
8310
  }, [visibleTasks, taskFilter]);
7781
- const taskListHighlightedTaskIds = (0, import_react13.useMemo)(() => {
8311
+ const taskListHighlightedTaskIds = (0, import_react15.useMemo)(() => {
7782
8312
  if (filterMode === "hide") {
7783
8313
  return /* @__PURE__ */ new Set();
7784
8314
  }
@@ -7789,23 +8319,23 @@ function GanttChartInner(props, ref) {
7789
8319
  matchedTaskIds.forEach((taskId) => mergedHighlightedTaskIds.add(taskId));
7790
8320
  return mergedHighlightedTaskIds;
7791
8321
  }, [filterMode, highlightedTaskIds, matchedTaskIds]);
7792
- const totalGridHeight = (0, import_react13.useMemo)(
8322
+ const totalGridHeight = (0, import_react15.useMemo)(
7793
8323
  () => visibleTasks.length * rowHeight,
7794
8324
  [visibleTasks.length, rowHeight]
7795
8325
  );
7796
- const monthStart = (0, import_react13.useMemo)(() => {
8326
+ const monthStart = (0, import_react15.useMemo)(() => {
7797
8327
  if (dateRange.length === 0) {
7798
8328
  return new Date(Date.UTC((/* @__PURE__ */ new Date()).getUTCFullYear(), (/* @__PURE__ */ new Date()).getUTCMonth(), 1));
7799
8329
  }
7800
8330
  const firstDay = dateRange[0];
7801
8331
  return new Date(Date.UTC(firstDay.getUTCFullYear(), firstDay.getUTCMonth(), 1));
7802
8332
  }, [dateRange]);
7803
- const todayInRange = (0, import_react13.useMemo)(() => {
8333
+ const todayInRange = (0, import_react15.useMemo)(() => {
7804
8334
  const now = /* @__PURE__ */ new Date();
7805
8335
  const today = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()));
7806
8336
  return dateRange.some((day) => day.getTime() === today.getTime());
7807
8337
  }, [dateRange]);
7808
- (0, import_react13.useEffect)(() => {
8338
+ (0, import_react15.useEffect)(() => {
7809
8339
  const container = scrollContainerRef.current;
7810
8340
  if (!container || dateRange.length === 0) return;
7811
8341
  const now = /* @__PURE__ */ new Date();
@@ -7817,7 +8347,7 @@ function GanttChartInner(props, ref) {
7817
8347
  const scrollLeft = Math.round(todayOffset + dayWidth / 2 - containerWidth * 0.3);
7818
8348
  container.scrollLeft = Math.max(0, scrollLeft);
7819
8349
  }, []);
7820
- (0, import_react13.useEffect)(() => {
8350
+ (0, import_react15.useEffect)(() => {
7821
8351
  const container = scrollContainerRef.current;
7822
8352
  if (!container) return;
7823
8353
  const updateShadow = () => {
@@ -7829,7 +8359,7 @@ function GanttChartInner(props, ref) {
7829
8359
  container.removeEventListener("scroll", updateShadow);
7830
8360
  };
7831
8361
  }, []);
7832
- const scrollToToday = (0, import_react13.useCallback)(() => {
8362
+ const scrollToToday = (0, import_react15.useCallback)(() => {
7833
8363
  const container = scrollContainerRef.current;
7834
8364
  if (!container || dateRange.length === 0) return;
7835
8365
  const now = /* @__PURE__ */ new Date();
@@ -7841,7 +8371,7 @@ function GanttChartInner(props, ref) {
7841
8371
  const scrollLeft = Math.round(todayOffset + dayWidth / 2 - containerWidth * 0.3);
7842
8372
  container.scrollTo({ left: Math.max(0, scrollLeft), behavior: "smooth" });
7843
8373
  }, [dateRange, dayWidth]);
7844
- const scrollToTask = (0, import_react13.useCallback)((taskId) => {
8374
+ const scrollToTask = (0, import_react15.useCallback)((taskId) => {
7845
8375
  const container = scrollContainerRef.current;
7846
8376
  if (!container || dateRange.length === 0) return;
7847
8377
  const task = tasks.find((t) => t.id === taskId);
@@ -7858,7 +8388,7 @@ function GanttChartInner(props, ref) {
7858
8388
  const scrollLeft = Math.round(taskOffset - dayWidth * 2);
7859
8389
  container.scrollTo({ left: Math.max(0, scrollLeft), behavior: "smooth" });
7860
8390
  }, [tasks, dateRange, dayWidth]);
7861
- const scrollToRow = (0, import_react13.useCallback)((taskId) => {
8391
+ const scrollToRow = (0, import_react15.useCallback)((taskId) => {
7862
8392
  const container = scrollContainerRef.current;
7863
8393
  if (!container) return;
7864
8394
  const task = tasks.find((t) => t.id === taskId);
@@ -7870,15 +8400,15 @@ function GanttChartInner(props, ref) {
7870
8400
  setSelectedTaskId(taskId);
7871
8401
  container.scrollTo({ top: scrollTop, behavior: "smooth" });
7872
8402
  }, [tasks, visibleTasks, rowHeight]);
7873
- const [dragGuideLines, setDragGuideLines] = (0, import_react13.useState)(null);
7874
- const [draggedTaskOverride, setDraggedTaskOverride] = (0, import_react13.useState)(null);
7875
- const [previewTasksById, setPreviewTasksById] = (0, import_react13.useState)(/* @__PURE__ */ new Map());
7876
- (0, import_react13.useEffect)(() => {
8403
+ const [dragGuideLines, setDragGuideLines] = (0, import_react15.useState)(null);
8404
+ const [draggedTaskOverride, setDraggedTaskOverride] = (0, import_react15.useState)(null);
8405
+ const [previewTasksById, setPreviewTasksById] = (0, import_react15.useState)(/* @__PURE__ */ new Map());
8406
+ (0, import_react15.useEffect)(() => {
7877
8407
  const result = validateDependencies(tasks);
7878
8408
  setValidationResult(result);
7879
8409
  onValidateDependencies?.(result);
7880
8410
  }, [tasks, onValidateDependencies]);
7881
- const handleTaskChange = (0, import_react13.useCallback)((updatedTasks) => {
8411
+ const handleTaskChange = (0, import_react15.useCallback)((updatedTasks) => {
7882
8412
  const updatedTask = updatedTasks[0];
7883
8413
  if (!updatedTask) return;
7884
8414
  const originalTask = tasks.find((t) => t.id === updatedTask.id);
@@ -7924,7 +8454,7 @@ function GanttChartInner(props, ref) {
7924
8454
  const cascadedTasks = disableConstraints ? [updatedTask] : universalCascade(updatedTask, newStart, newEnd, sourceTasks, businessDays, isCustomWeekend);
7925
8455
  onTasksChange?.(cascadedTasks);
7926
8456
  }, [tasks, onTasksChange, disableConstraints, editingTaskId, businessDays, isCustomWeekend]);
7927
- const handleDelete = (0, import_react13.useCallback)((taskId) => {
8457
+ const handleDelete = (0, import_react15.useCallback)((taskId) => {
7928
8458
  const toDelete = /* @__PURE__ */ new Set([taskId]);
7929
8459
  function collectDescendants(parentId) {
7930
8460
  const children = getChildren(parentId, tasks);
@@ -7949,10 +8479,10 @@ function GanttChartInner(props, ref) {
7949
8479
  }
7950
8480
  toDelete.forEach((id) => onDelete?.(id));
7951
8481
  }, [tasks, onTasksChange, onDelete]);
7952
- const handleInsertAfter = (0, import_react13.useCallback)((taskId, newTask) => {
8482
+ const handleInsertAfter = (0, import_react15.useCallback)((taskId, newTask) => {
7953
8483
  onInsertAfter?.(taskId, newTask);
7954
8484
  }, [onInsertAfter]);
7955
- const handleReorder = (0, import_react13.useCallback)((reorderedTasks, movedTaskId, inferredParentId) => {
8485
+ const handleReorder = (0, import_react15.useCallback)((reorderedTasks, movedTaskId, inferredParentId) => {
7956
8486
  let updated = reorderedTasks;
7957
8487
  if (movedTaskId) {
7958
8488
  updated = updated.map((t) => {
@@ -7969,7 +8499,7 @@ function GanttChartInner(props, ref) {
7969
8499
  }
7970
8500
  onTasksChange?.(normalized);
7971
8501
  }, [onTasksChange, onReorder]);
7972
- const dependencyOverrides = (0, import_react13.useMemo)(() => {
8502
+ const dependencyOverrides = (0, import_react15.useMemo)(() => {
7973
8503
  const map = new Map(cascadeOverrides);
7974
8504
  if (draggedTaskOverride) {
7975
8505
  map.set(draggedTaskOverride.taskId, {
@@ -7979,25 +8509,25 @@ function GanttChartInner(props, ref) {
7979
8509
  }
7980
8510
  return map;
7981
8511
  }, [cascadeOverrides, draggedTaskOverride]);
7982
- const handleCascadeProgress = (0, import_react13.useCallback)((overrides, previewTasks = []) => {
8512
+ const handleCascadeProgress = (0, import_react15.useCallback)((overrides, previewTasks = []) => {
7983
8513
  setCascadeOverrides(new Map(overrides));
7984
8514
  setPreviewTasksById(new Map(previewTasks.map((task) => [task.id, task])));
7985
8515
  }, []);
7986
- const previewNormalizedTasks = (0, import_react13.useMemo)(() => {
8516
+ const previewNormalizedTasks = (0, import_react15.useMemo)(() => {
7987
8517
  if (previewTasksById.size === 0) return normalizedTasks;
7988
8518
  return normalizedTasks.map((task) => previewTasksById.get(task.id) ?? task);
7989
8519
  }, [normalizedTasks, previewTasksById]);
7990
- const previewVisibleTasks = (0, import_react13.useMemo)(() => {
8520
+ const previewVisibleTasks = (0, import_react15.useMemo)(() => {
7991
8521
  if (previewTasksById.size === 0) return visibleTasks;
7992
8522
  return visibleTasks.map((task) => previewTasksById.get(task.id) ?? task);
7993
8523
  }, [visibleTasks, previewTasksById]);
7994
- const handleCascade = (0, import_react13.useCallback)((cascadedTasks) => {
8524
+ const handleCascade = (0, import_react15.useCallback)((cascadedTasks) => {
7995
8525
  onTasksChange?.(cascadedTasks);
7996
8526
  }, [tasks, onTasksChange]);
7997
- const handleTaskSelect = (0, import_react13.useCallback)((taskId) => {
8527
+ const handleTaskSelect = (0, import_react15.useCallback)((taskId) => {
7998
8528
  setSelectedTaskId(taskId);
7999
8529
  }, []);
8000
- const handleToggleCollapse = externalOnToggleCollapse ?? (0, import_react13.useCallback)((parentId) => {
8530
+ const handleToggleCollapse = externalOnToggleCollapse ?? (0, import_react15.useCallback)((parentId) => {
8001
8531
  setInternalCollapsedParentIds((prev) => {
8002
8532
  const next = new Set(prev);
8003
8533
  if (next.has(parentId)) {
@@ -8008,20 +8538,20 @@ function GanttChartInner(props, ref) {
8008
8538
  return next;
8009
8539
  });
8010
8540
  }, []);
8011
- const allParentIds = (0, import_react13.useMemo)(() => {
8541
+ const allParentIds = (0, import_react15.useMemo)(() => {
8012
8542
  return new Set(
8013
8543
  normalizedTasks.filter((t) => isTaskParent(t.id, normalizedTasks)).map((t) => t.id)
8014
8544
  );
8015
8545
  }, [normalizedTasks]);
8016
- const handleCollapseAll = (0, import_react13.useCallback)(() => {
8546
+ const handleCollapseAll = (0, import_react15.useCallback)(() => {
8017
8547
  if (externalCollapsedParentIds) return;
8018
8548
  setInternalCollapsedParentIds(allParentIds);
8019
8549
  }, [allParentIds, externalCollapsedParentIds]);
8020
- const handleExpandAll = (0, import_react13.useCallback)(() => {
8550
+ const handleExpandAll = (0, import_react15.useCallback)(() => {
8021
8551
  if (externalCollapsedParentIds) return;
8022
8552
  setInternalCollapsedParentIds(/* @__PURE__ */ new Set());
8023
8553
  }, [externalCollapsedParentIds]);
8024
- const exportToPdf = (0, import_react13.useCallback)(async (options) => {
8554
+ const exportToPdf = (0, import_react15.useCallback)(async (options) => {
8025
8555
  const sourceContainer = containerRef.current;
8026
8556
  const sourceContent = scrollContentRef.current;
8027
8557
  if (!sourceContainer || !sourceContent || typeof window === "undefined" || typeof document === "undefined") {
@@ -8057,7 +8587,7 @@ function GanttChartInner(props, ref) {
8057
8587
  orientation: options?.orientation
8058
8588
  });
8059
8589
  }, [showTaskList, showChart]);
8060
- (0, import_react13.useImperativeHandle)(
8590
+ (0, import_react15.useImperativeHandle)(
8061
8591
  ref,
8062
8592
  () => ({
8063
8593
  scrollToToday,
@@ -8080,7 +8610,7 @@ function GanttChartInner(props, ref) {
8080
8610
  }
8081
8611
  return depth;
8082
8612
  }
8083
- const handlePromoteTask = (0, import_react13.useCallback)((taskId) => {
8613
+ const handlePromoteTask = (0, import_react15.useCallback)((taskId) => {
8084
8614
  if (onPromoteTask) {
8085
8615
  onPromoteTask(taskId);
8086
8616
  return;
@@ -8110,7 +8640,7 @@ function GanttChartInner(props, ref) {
8110
8640
  ]);
8111
8641
  onTasksChange?.(reorderedTasks);
8112
8642
  }, [tasks, onTasksChange, onPromoteTask]);
8113
- const handleDemoteTask = (0, import_react13.useCallback)((taskId, newParentId) => {
8643
+ const handleDemoteTask = (0, import_react15.useCallback)((taskId, newParentId) => {
8114
8644
  if (onDemoteTask) {
8115
8645
  onDemoteTask(taskId, newParentId);
8116
8646
  return;
@@ -8151,7 +8681,7 @@ function GanttChartInner(props, ref) {
8151
8681
  };
8152
8682
  onTasksChange?.([updatedDemotedTask]);
8153
8683
  }, [tasks, onTasksChange, onDemoteTask]);
8154
- const handleUngroupTask = (0, import_react13.useCallback)((taskId) => {
8684
+ const handleUngroupTask = (0, import_react15.useCallback)((taskId) => {
8155
8685
  if (onUngroupTask) {
8156
8686
  onUngroupTask(taskId);
8157
8687
  return;
@@ -8178,8 +8708,8 @@ function GanttChartInner(props, ref) {
8178
8708
  }
8179
8709
  onDelete?.(taskId);
8180
8710
  }, [tasks, onTasksChange, onDelete, onUngroupTask]);
8181
- const panStateRef = (0, import_react13.useRef)(null);
8182
- const handlePanStart = (0, import_react13.useCallback)((e) => {
8711
+ const panStateRef = (0, import_react15.useRef)(null);
8712
+ const handlePanStart = (0, import_react15.useCallback)((e) => {
8183
8713
  if (e.button !== 0) return;
8184
8714
  const target = e.target;
8185
8715
  if (target.closest("[data-taskbar]")) return;
@@ -8200,7 +8730,7 @@ function GanttChartInner(props, ref) {
8200
8730
  container.style.cursor = "grabbing";
8201
8731
  e.preventDefault();
8202
8732
  }, []);
8203
- (0, import_react13.useEffect)(() => {
8733
+ (0, import_react15.useEffect)(() => {
8204
8734
  const handlePanMove = (e) => {
8205
8735
  const pan = panStateRef.current;
8206
8736
  if (!pan?.active) return;
@@ -8222,15 +8752,15 @@ function GanttChartInner(props, ref) {
8222
8752
  window.removeEventListener("mouseup", handlePanEnd);
8223
8753
  };
8224
8754
  }, []);
8225
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { ref: containerRef, className: "gantt-container", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
8755
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { ref: containerRef, className: "gantt-container", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8226
8756
  "div",
8227
8757
  {
8228
8758
  ref: scrollContainerRef,
8229
8759
  className: "gantt-scrollContainer",
8230
8760
  style: { height: containerHeight ?? "auto", cursor: "grab" },
8231
8761
  onMouseDown: handlePanStart,
8232
- children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { ref: scrollContentRef, className: "gantt-scrollContent", children: [
8233
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
8762
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { ref: scrollContentRef, className: "gantt-scrollContent", children: [
8763
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8234
8764
  TaskList,
8235
8765
  {
8236
8766
  tasks: normalizedTasks,
@@ -8268,13 +8798,13 @@ function GanttChartInner(props, ref) {
8268
8798
  taskListMenuCommands
8269
8799
  }
8270
8800
  ),
8271
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
8801
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
8272
8802
  "div",
8273
8803
  {
8274
8804
  className: showChart ? "gantt-chartSurface" : "gantt-chartSurface gantt-chart-hidden",
8275
8805
  style: { minWidth: `${gridWidth}px`, flex: 1, display: showChart ? void 0 : "none" },
8276
8806
  children: [
8277
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "gantt-stickyHeader", style: { width: `${gridWidth}px` }, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
8807
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "gantt-stickyHeader", style: { width: `${gridWidth}px` }, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8278
8808
  TimeScaleHeader_default,
8279
8809
  {
8280
8810
  days: dateRange,
@@ -8284,7 +8814,7 @@ function GanttChartInner(props, ref) {
8284
8814
  isCustomWeekend
8285
8815
  }
8286
8816
  ) }),
8287
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
8817
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
8288
8818
  "div",
8289
8819
  {
8290
8820
  className: "gantt-taskArea",
@@ -8293,7 +8823,7 @@ function GanttChartInner(props, ref) {
8293
8823
  width: `${gridWidth}px`
8294
8824
  },
8295
8825
  children: [
8296
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
8826
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8297
8827
  GridBackground_default,
8298
8828
  {
8299
8829
  dateRange,
@@ -8303,8 +8833,8 @@ function GanttChartInner(props, ref) {
8303
8833
  isCustomWeekend
8304
8834
  }
8305
8835
  ),
8306
- todayInRange && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TodayIndicator_default, { monthStart, dayWidth }),
8307
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
8836
+ todayInRange && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TodayIndicator_default, { monthStart, dayWidth }),
8837
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8308
8838
  DependencyLines_default,
8309
8839
  {
8310
8840
  tasks: previewVisibleTasks,
@@ -8320,7 +8850,7 @@ function GanttChartInner(props, ref) {
8320
8850
  weekendPredicate: isCustomWeekend
8321
8851
  }
8322
8852
  ),
8323
- dragGuideLines && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
8853
+ dragGuideLines && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8324
8854
  DragGuideLines_default,
8325
8855
  {
8326
8856
  isDragging: dragGuideLines.isDragging,
@@ -8330,7 +8860,7 @@ function GanttChartInner(props, ref) {
8330
8860
  totalHeight: totalGridHeight
8331
8861
  }
8332
8862
  ),
8333
- visibleTasks.map((task, index) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
8863
+ visibleTasks.map((task, index) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8334
8864
  TaskRow_default,
8335
8865
  {
8336
8866
  task,
@@ -8374,13 +8904,14 @@ function GanttChartInner(props, ref) {
8374
8904
  }
8375
8905
  ) });
8376
8906
  }
8377
- var GanttChart = (0, import_react13.forwardRef)(GanttChartInner);
8907
+ var TaskGanttChart = (0, import_react15.forwardRef)(TaskGanttChartInner);
8908
+ var GanttChart = (0, import_react15.forwardRef)(GanttChartInner);
8378
8909
  GanttChart.displayName = "GanttChart";
8379
8910
 
8380
8911
  // src/components/ui/Button.tsx
8381
- var import_react14 = __toESM(require("react"));
8382
- var import_jsx_runtime16 = require("react/jsx-runtime");
8383
- var Button = import_react14.default.forwardRef(
8912
+ var import_react16 = __toESM(require("react"));
8913
+ var import_jsx_runtime17 = require("react/jsx-runtime");
8914
+ var Button = import_react16.default.forwardRef(
8384
8915
  ({ className, variant = "default", size = "default", children, ...props }, ref) => {
8385
8916
  const classes = [
8386
8917
  "gantt-btn",
@@ -8388,7 +8919,7 @@ var Button = import_react14.default.forwardRef(
8388
8919
  size !== "default" ? `gantt-btn-${size}` : "",
8389
8920
  className || ""
8390
8921
  ].filter(Boolean).join(" ");
8391
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { ref, className: classes, ...props, children });
8922
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("button", { ref, className: classes, ...props, children });
8392
8923
  }
8393
8924
  );
8394
8925
  Button.displayName = "Button";
@@ -8434,6 +8965,7 @@ var nameContains = (substring, caseSensitive = false) => (task) => {
8434
8965
  Popover,
8435
8966
  PopoverContent,
8436
8967
  PopoverTrigger,
8968
+ ResourceTimelineChart,
8437
8969
  TaskList,
8438
8970
  TaskRow,
8439
8971
  TimeScaleHeader,
@@ -8497,6 +9029,7 @@ var nameContains = (substring, caseSensitive = false) => (task) => {
8497
9029
  isTaskParent,
8498
9030
  isToday,
8499
9031
  isWeekend,
9032
+ layoutResourceTimelineItems,
8500
9033
  moveTaskRange,
8501
9034
  moveTaskWithCascade,
8502
9035
  nameContains,