gantt-lib 0.136.0 → 0.136.1

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.d.mts CHANGED
@@ -635,6 +635,8 @@ interface TaskChartSharedProps<TTask extends Task = Task> {
635
635
  showTaskDateLabels?: boolean;
636
636
  /** Render task names to the right of task bars in Gantt mode (default: true). */
637
637
  showTaskNames?: boolean;
638
+ /** Render composite child mini-bars inside the parent bar (default: true). */
639
+ showCompositeSegments?: boolean;
638
640
  /** Optional vertical timeline markers such as deadlines and checkpoints. */
639
641
  timelineMarkers?: TimelineMarker[];
640
642
  /** Additional custom columns to render in the TaskList after built-in columns */
@@ -847,6 +849,8 @@ interface TaskRowProps {
847
849
  showTaskDateLabels?: boolean;
848
850
  /** Render the task name to the right of the task bar (default: true). */
849
851
  showTaskNames?: boolean;
852
+ /** Render composite child mini-bars inside the parent bar (default: true). */
853
+ showCompositeSegments?: boolean;
850
854
  /** Open or close the composite detail rows. */
851
855
  onCompositeToggle?: (source: 'release' | 'click' | 'keyboard') => void;
852
856
  compactDetail?: boolean;
package/dist/index.d.ts CHANGED
@@ -635,6 +635,8 @@ interface TaskChartSharedProps<TTask extends Task = Task> {
635
635
  showTaskDateLabels?: boolean;
636
636
  /** Render task names to the right of task bars in Gantt mode (default: true). */
637
637
  showTaskNames?: boolean;
638
+ /** Render composite child mini-bars inside the parent bar (default: true). */
639
+ showCompositeSegments?: boolean;
638
640
  /** Optional vertical timeline markers such as deadlines and checkpoints. */
639
641
  timelineMarkers?: TimelineMarker[];
640
642
  /** Additional custom columns to render in the TaskList after built-in columns */
@@ -847,6 +849,8 @@ interface TaskRowProps {
847
849
  showTaskDateLabels?: boolean;
848
850
  /** Render the task name to the right of the task bar (default: true). */
849
851
  showTaskNames?: boolean;
852
+ /** Render composite child mini-bars inside the parent bar (default: true). */
853
+ showCompositeSegments?: boolean;
850
854
  /** Open or close the composite detail rows. */
851
855
  onCompositeToggle?: (source: 'release' | 'click' | 'keyboard') => void;
852
856
  compactDetail?: boolean;
package/dist/index.js CHANGED
@@ -4414,16 +4414,17 @@ var useTaskDrag = (options) => {
4414
4414
 
4415
4415
  // src/components/TaskRow/TaskRow.tsx
4416
4416
  var import_jsx_runtime2 = require("react/jsx-runtime");
4417
+ var COMPOSITE_SEGMENT_CUT_MIN_PX = 10;
4417
4418
  var formatCompositePreviewDate = (date) => {
4418
4419
  const month = new Intl.DateTimeFormat("ru-RU", { month: "short", timeZone: "UTC" }).format(date).replace(/\.$/, "");
4419
4420
  const yearSuffix = date.getUTCFullYear() === (/* @__PURE__ */ new Date()).getFullYear() ? "" : ` ${String(date.getUTCFullYear()).slice(-2)}`;
4420
4421
  return `${date.getUTCDate()} ${month}${yearSuffix}`;
4421
4422
  };
4422
4423
  var arePropsEqual = (prevProps, nextProps) => {
4423
- return prevProps.task.id === nextProps.task.id && prevProps.task.name === nextProps.task.name && prevProps.task.startDate === nextProps.task.startDate && prevProps.task.endDate === nextProps.task.endDate && prevProps.task.baselineStartDate === nextProps.task.baselineStartDate && prevProps.task.baselineEndDate === nextProps.task.baselineEndDate && prevProps.task.type === nextProps.task.type && prevProps.task.color === nextProps.task.color && prevProps.task.progress === nextProps.task.progress && prevProps.task.accepted === nextProps.task.accepted && prevProps.monthStart.getTime() === nextProps.monthStart.getTime() && prevProps.dayWidth === nextProps.dayWidth && prevProps.rowHeight === nextProps.rowHeight && prevProps.overridePosition?.left === nextProps.overridePosition?.left && prevProps.overridePosition?.width === nextProps.overridePosition?.width && prevProps.previewPositionStore === nextProps.previewPositionStore && prevProps.allTasks === nextProps.allTasks && prevProps.disableConstraints === nextProps.disableConstraints && prevProps.deferCascadePreview === nextProps.deferCascadePreview && prevProps.task.locked === nextProps.task.locked && prevProps.task.synced === nextProps.task.synced && prevProps.task.divider === nextProps.task.divider && prevProps.highlightExpiredTasks === nextProps.highlightExpiredTasks && prevProps.isCritical === nextProps.isCritical && prevProps.showBaseline === nextProps.showBaseline && prevProps.onCompositeToggle === nextProps.onCompositeToggle && prevProps.compactDetail === nextProps.compactDetail && prevProps.compositeParentColor === nextProps.compositeParentColor && prevProps.compositeExpanded === nextProps.compositeExpanded && prevProps.isFilterMatch === nextProps.isFilterMatch && prevProps.businessDays === nextProps.businessDays && prevProps.customDays === nextProps.customDays && prevProps.isWeekend === nextProps.isWeekend && prevProps.disableTaskDrag === nextProps.disableTaskDrag && prevProps.disableDependencyEditing === nextProps.disableDependencyEditing && prevProps.isDependencyDragActive === nextProps.isDependencyDragActive && prevProps.viewMode === nextProps.viewMode && prevProps.showTaskDateLabels === nextProps.showTaskDateLabels && prevProps.showTaskNames === nextProps.showTaskNames;
4424
+ return prevProps.task.id === nextProps.task.id && prevProps.task.name === nextProps.task.name && prevProps.task.startDate === nextProps.task.startDate && prevProps.task.endDate === nextProps.task.endDate && prevProps.task.baselineStartDate === nextProps.task.baselineStartDate && prevProps.task.baselineEndDate === nextProps.task.baselineEndDate && prevProps.task.type === nextProps.task.type && prevProps.task.color === nextProps.task.color && prevProps.task.progress === nextProps.task.progress && prevProps.task.accepted === nextProps.task.accepted && prevProps.monthStart.getTime() === nextProps.monthStart.getTime() && prevProps.dayWidth === nextProps.dayWidth && prevProps.rowHeight === nextProps.rowHeight && prevProps.overridePosition?.left === nextProps.overridePosition?.left && prevProps.overridePosition?.width === nextProps.overridePosition?.width && prevProps.previewPositionStore === nextProps.previewPositionStore && prevProps.allTasks === nextProps.allTasks && prevProps.disableConstraints === nextProps.disableConstraints && prevProps.deferCascadePreview === nextProps.deferCascadePreview && prevProps.task.locked === nextProps.task.locked && prevProps.task.synced === nextProps.task.synced && prevProps.task.divider === nextProps.task.divider && prevProps.highlightExpiredTasks === nextProps.highlightExpiredTasks && prevProps.isCritical === nextProps.isCritical && prevProps.showBaseline === nextProps.showBaseline && prevProps.onCompositeToggle === nextProps.onCompositeToggle && prevProps.compactDetail === nextProps.compactDetail && prevProps.compositeParentColor === nextProps.compositeParentColor && prevProps.compositeExpanded === nextProps.compositeExpanded && prevProps.isFilterMatch === nextProps.isFilterMatch && prevProps.businessDays === nextProps.businessDays && prevProps.customDays === nextProps.customDays && prevProps.isWeekend === nextProps.isWeekend && prevProps.disableTaskDrag === nextProps.disableTaskDrag && prevProps.disableDependencyEditing === nextProps.disableDependencyEditing && prevProps.isDependencyDragActive === nextProps.isDependencyDragActive && prevProps.viewMode === nextProps.viewMode && prevProps.showTaskDateLabels === nextProps.showTaskDateLabels && prevProps.showTaskNames === nextProps.showTaskNames && prevProps.showCompositeSegments === nextProps.showCompositeSegments;
4424
4425
  };
4425
4426
  var TaskRow = import_react3.default.memo(
4426
- ({ task, monthStart, dayWidth, rowHeight, onTasksChange, onScheduleIntent, onDragStateChange, rowIndex, allTasks, enableAutoSchedule, disableConstraints, deferCascadePreview = false, overridePosition, previewPositionStore, onCascadeProgress, onCascade, divider, highlightExpiredTasks, isCritical = false, showBaseline = false, isFilterMatch = false, businessDays, customDays, isWeekend: isWeekend3, disableTaskDrag = false, disableDependencyEditing = false, onDependencyPortPointerDown, isDependencyDragActive = false, viewMode = "day", showTaskDateLabels = true, showTaskNames = true, onCompositeToggle, compactDetail = false, compositeParentColor, compositeExpanded = false }) => {
4427
+ ({ task, monthStart, dayWidth, rowHeight, onTasksChange, onScheduleIntent, onDragStateChange, rowIndex, allTasks, enableAutoSchedule, disableConstraints, deferCascadePreview = false, overridePosition, previewPositionStore, onCascadeProgress, onCascade, divider, highlightExpiredTasks, isCritical = false, showBaseline = false, isFilterMatch = false, businessDays, customDays, isWeekend: isWeekend3, disableTaskDrag = false, disableDependencyEditing = false, onDependencyPortPointerDown, isDependencyDragActive = false, viewMode = "day", showTaskDateLabels = true, showTaskNames = true, showCompositeSegments: showCompositeSegmentsProp = true, onCompositeToggle, compactDetail = false, compositeParentColor, compositeExpanded = false }) => {
4427
4428
  const defaultParentBarColor = "#782FC4";
4428
4429
  const [showCompositePreview, setShowCompositePreview] = (0, import_react3.useState)(false);
4429
4430
  const [compositePreviewPosition, setCompositePreviewPosition] = (0, import_react3.useState)(null);
@@ -4605,22 +4606,32 @@ var TaskRow = import_react3.default.memo(
4605
4606
  const compositeSegments = (0, import_react3.useMemo)(() => {
4606
4607
  if (!task.composite || width <= 0) return [];
4607
4608
  const laneEnds = [];
4608
- return compositeChildren.map((child) => {
4609
+ const segments2 = compositeChildren.map((child) => {
4609
4610
  const segment = calculateTaskBar(parseUTCDate(child.startDate), parseUTCDate(child.endDate), monthStart, dayWidth);
4610
- let lane = laneEnds.findIndex((end) => end <= segment.left);
4611
- if (lane < 0) lane = laneEnds.length;
4611
+ let lane = Math.max(0, laneEnds.length - 1);
4612
+ if (laneEnds.length > 0 && segment.left < laneEnds[lane]) {
4613
+ lane = laneEnds.length;
4614
+ }
4612
4615
  laneEnds[lane] = segment.left + segment.width;
4613
4616
  return {
4614
4617
  id: child.id,
4615
4618
  name: child.name,
4616
4619
  left: (segment.left - left) / width * 100,
4617
4620
  width: segment.width / width * 100,
4618
- lane
4621
+ lane,
4622
+ pxLeft: segment.left - left,
4623
+ cut: false
4619
4624
  };
4620
4625
  });
4626
+ const lastCutByLane = [];
4627
+ for (const segment of [...segments2].sort((a, b) => a.pxLeft - b.pxLeft)) {
4628
+ segment.cut = segment.pxLeft >= 1 && segment.pxLeft - (lastCutByLane[segment.lane] ?? 0) >= COMPOSITE_SEGMENT_CUT_MIN_PX;
4629
+ if (segment.cut) lastCutByLane[segment.lane] = segment.pxLeft;
4630
+ }
4631
+ return segments2;
4621
4632
  }, [task.composite, compositeChildren, monthStart, dayWidth, left, width, displayLeft]);
4622
4633
  const compositeLaneCount = Math.max(1, ...compositeSegments.map((segment) => segment.lane + 1));
4623
- const showCompositeSegments = task.composite && compositeSegments.length > 0 && visualWidth / compositeSegments.length >= 22;
4634
+ const shouldRenderCompositeSegments = showCompositeSegmentsProp && task.composite && compositeSegments.length > 0 && visualWidth / compositeSegments.length >= 22;
4624
4635
  const shouldRenderBaseline = showBaseline && baselineGeometry !== null;
4625
4636
  const hasPreviewPosition = isDragging || effectiveOverridePosition !== void 0;
4626
4637
  const currentStartDate = hasPreviewPosition ? pixelsToDate(displayLeft, monthStart, dayWidth) : taskStartDate;
@@ -4749,19 +4760,33 @@ var TaskRow = import_react3.default.memo(
4749
4760
  }
4750
4761
  ),
4751
4762
  !milestone && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "gantt-tr-resizeHandle gantt-tr-resizeHandleLeft" }),
4752
- showCompositeSegments && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "gantt-tr-compositeSegments", "aria-hidden": "true", children: compositeSegments.map((segment) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4753
- "span",
4754
- {
4755
- className: "gantt-tr-compositeSegment",
4756
- style: {
4757
- left: `${segment.left}%`,
4758
- width: `${segment.width}%`,
4759
- top: `${segment.lane / compositeLaneCount * 100}%`,
4760
- height: `${100 / compositeLaneCount}%`
4761
- }
4762
- },
4763
- segment.id
4764
- )) }),
4763
+ shouldRenderCompositeSegments && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "gantt-tr-compositeSegments", "aria-hidden": "true", children: [
4764
+ compositeSegments.map((segment) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4765
+ "span",
4766
+ {
4767
+ className: "gantt-tr-compositeSegment",
4768
+ style: {
4769
+ left: `${segment.left}%`,
4770
+ width: `${segment.width}%`,
4771
+ top: `${segment.lane / compositeLaneCount * 100}%`,
4772
+ height: `${100 / compositeLaneCount}%`
4773
+ }
4774
+ },
4775
+ segment.id
4776
+ )),
4777
+ compositeSegments.map((segment) => segment.cut ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4778
+ "span",
4779
+ {
4780
+ className: "gantt-tr-compositeSegmentCut",
4781
+ style: {
4782
+ left: `${segment.left}%`,
4783
+ top: `${segment.lane / compositeLaneCount * 100}%`,
4784
+ height: `${100 / compositeLaneCount}%`
4785
+ }
4786
+ },
4787
+ `${segment.id}-cut`
4788
+ ) : null)
4789
+ ] }),
4765
4790
  task.composite && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "gantt-tr-compositeHoverChevron", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { className: `gantt-tr-compositeChevron${compositeExpanded ? " gantt-tr-compositeChevron-open" : ""}`, viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m7 4 6 6-6 6", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }) }),
4766
4791
  showDurationInside && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "gantt-tr-taskDuration", children: isVisualParent ? getChildCountLabel(childCount) : `${durationDays} \u0434` }),
4767
4792
  progressWidth > 0 && showProgressInside && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "gantt-tr-progressText", children: [
@@ -14469,6 +14494,7 @@ function TaskGanttChartInner(props, ref) {
14469
14494
  skeletonStartJitterDays = 0,
14470
14495
  showTaskDateLabels = true,
14471
14496
  showTaskNames = true,
14497
+ showCompositeSegments = true,
14472
14498
  timelineMarkers,
14473
14499
  additionalColumns,
14474
14500
  hiddenTaskListColumns,
@@ -14690,8 +14716,8 @@ function TaskGanttChartInner(props, ref) {
14690
14716
  const resolvedRowContentLines = isPlanFactMode ? Math.max(2, Math.floor(rowContentLines)) : Math.max(1, Math.floor(rowContentLines));
14691
14717
  const shouldFillParentRowsInTaskList = fillParentRowsInTaskList ?? isPlanFactMode;
14692
14718
  const effectiveRowHeight = (0, import_react19.useMemo)(
14693
- () => Math.max(rowHeight, 10 + resolvedRowContentLines * 18),
14694
- [resolvedRowContentLines, rowHeight]
14719
+ () => rowContentLines === 0 && !isPlanFactMode ? rowHeight : Math.max(rowHeight, 10 + resolvedRowContentLines * 18),
14720
+ [isPlanFactMode, resolvedRowContentLines, rowContentLines, rowHeight]
14695
14721
  );
14696
14722
  const normalizedTasks = (0, import_react19.useMemo)(() => {
14697
14723
  const ordered = normalizeHierarchyTasks(tasks);
@@ -16035,6 +16061,7 @@ function TaskGanttChartInner(props, ref) {
16035
16061
  viewMode,
16036
16062
  showTaskDateLabels,
16037
16063
  showTaskNames,
16064
+ showCompositeSegments,
16038
16065
  onCompositeToggle: task.composite ? (source) => handleCompositeBarToggle(task.id, source) : void 0,
16039
16066
  compositeExpanded: task.composite ? !collapsedParentIds.has(task.id) : void 0
16040
16067
  }