gantt-lib 0.113.1 → 0.115.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.d.mts CHANGED
@@ -414,8 +414,9 @@ interface PlanFactMatrixProps<TTask extends Task = Task> {
414
414
  visibleRowIndices?: number[];
415
415
  visibleDateIndices?: number[];
416
416
  todayDateIndex?: number;
417
+ isCustomWeekend?: (date: Date) => boolean;
417
418
  }
418
- declare function PlanFactMatrix<TTask extends Task = Task>({ tasks, allTasks, dateRange, dayWidth, rowHeight, headerHeight, bodyMinHeight, selectedTaskId, onTaskSelect, onTasksChange, onCellCommit, highlightedTaskIds, filterMode, visibleRowIndices, visibleDateIndices, todayDateIndex, }: PlanFactMatrixProps<TTask>): react_jsx_runtime.JSX.Element;
419
+ declare function PlanFactMatrix<TTask extends Task = Task>({ tasks, allTasks, dateRange, dayWidth, rowHeight, headerHeight, bodyMinHeight, selectedTaskId, onTaskSelect, onTasksChange, onCellCommit, highlightedTaskIds, filterMode, visibleRowIndices, visibleDateIndices, todayDateIndex, isCustomWeekend, }: PlanFactMatrixProps<TTask>): react_jsx_runtime.JSX.Element;
419
420
 
420
421
  /**
421
422
  * Task data structure for Gantt chart
package/dist/index.d.ts CHANGED
@@ -414,8 +414,9 @@ interface PlanFactMatrixProps<TTask extends Task = Task> {
414
414
  visibleRowIndices?: number[];
415
415
  visibleDateIndices?: number[];
416
416
  todayDateIndex?: number;
417
+ isCustomWeekend?: (date: Date) => boolean;
417
418
  }
418
- declare function PlanFactMatrix<TTask extends Task = Task>({ tasks, allTasks, dateRange, dayWidth, rowHeight, headerHeight, bodyMinHeight, selectedTaskId, onTaskSelect, onTasksChange, onCellCommit, highlightedTaskIds, filterMode, visibleRowIndices, visibleDateIndices, todayDateIndex, }: PlanFactMatrixProps<TTask>): react_jsx_runtime.JSX.Element;
419
+ declare function PlanFactMatrix<TTask extends Task = Task>({ tasks, allTasks, dateRange, dayWidth, rowHeight, headerHeight, bodyMinHeight, selectedTaskId, onTaskSelect, onTasksChange, onCellCommit, highlightedTaskIds, filterMode, visibleRowIndices, visibleDateIndices, todayDateIndex, isCustomWeekend, }: PlanFactMatrixProps<TTask>): react_jsx_runtime.JSX.Element;
419
420
 
420
421
  /**
421
422
  * Task data structure for Gantt chart
package/dist/index.js CHANGED
@@ -10791,7 +10791,11 @@ function PlanFactRowInner({
10791
10791
  const planValue = task.planByDate?.[dateKey];
10792
10792
  const factValue = task.factByDate?.[dateKey];
10793
10793
  const value = kind === "plan" ? planValue : factValue;
10794
- const factStatus = factValue === void 0 || planValue === void 0 ? null : factValue >= planValue ? "success" : "warning";
10794
+ const isPastReportDate = todayDateIndex !== void 0 && dateIndex < todayDateIndex;
10795
+ const hasPlannedWork = (planValue ?? 0) > 0;
10796
+ const isMissingOrZeroFact = factValue === void 0 || factValue === 0;
10797
+ const isFactBelowPlan = kind === "fact" && factValue !== void 0 && planValue !== void 0 && factValue < planValue;
10798
+ const isPastDueMissingFact = kind === "fact" && isPastReportDate && hasPlannedWork && isMissingOrZeroFact;
10795
10799
  const isActive = activeCell?.taskId === task.id && activeCell.dateIndex === dateIndex && activeCell.kind === kind;
10796
10800
  const isEditing = editingCell?.taskId === task.id && editingCell.dateIndex === dateIndex && editingCell.kind === kind;
10797
10801
  const currentCell = { taskId: task.id, dateIndex, kind };
@@ -10809,8 +10813,7 @@ function PlanFactRowInner({
10809
10813
  `gantt-pf-cell-${kind}`,
10810
10814
  !isParent && planned && kind === "plan" && "gantt-pf-cell-planned",
10811
10815
  !isParent && value !== void 0 && "gantt-pf-cell-hasValue",
10812
- !isParent && kind === "fact" && factStatus === "success" && "gantt-pf-cell-factSuccess",
10813
- !isParent && kind === "fact" && factStatus === "warning" && "gantt-pf-cell-factWarning",
10816
+ !isParent && (isFactBelowPlan || isPastDueMissingFact) && "gantt-pf-cell-factWarning",
10814
10817
  isSelected && "gantt-pf-cell-selected",
10815
10818
  isInRenderedRange && renderedRangeBounds !== null && dateIndex === renderedRangeBounds.fromDateIndex && "gantt-pf-cell-rangeLeft",
10816
10819
  isInRenderedRange && renderedRangeBounds !== null && dateIndex === renderedRangeBounds.toDateIndex && "gantt-pf-cell-rangeRight",
@@ -10979,7 +10982,8 @@ function PlanFactMatrix({
10979
10982
  filterMode = "highlight",
10980
10983
  visibleRowIndices,
10981
10984
  visibleDateIndices,
10982
- todayDateIndex
10985
+ todayDateIndex,
10986
+ isCustomWeekend
10983
10987
  }) {
10984
10988
  const [activeCell, setActiveCell] = (0, import_react17.useState)(null);
10985
10989
  const [editingCell, setEditingCell] = (0, import_react17.useState)(null);
@@ -11458,7 +11462,8 @@ function PlanFactMatrix({
11458
11462
  days: dateRange,
11459
11463
  dayWidth,
11460
11464
  headerHeight: headerHeight - 1,
11461
- viewMode: "day"
11465
+ viewMode: "day",
11466
+ isCustomWeekend
11462
11467
  }
11463
11468
  ),
11464
11469
  todayDateIndex !== void 0 && todayDateIndex >= 0 && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
@@ -11484,7 +11489,7 @@ function PlanFactMatrix({
11484
11489
  },
11485
11490
  `month-separator-${dateIndex}`
11486
11491
  )) }),
11487
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
11492
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
11488
11493
  "div",
11489
11494
  {
11490
11495
  ref: bodyRef,
@@ -11494,52 +11499,65 @@ function PlanFactMatrix({
11494
11499
  minHeight: bodyMinHeight,
11495
11500
  width: `${totalWidth}px`
11496
11501
  },
11497
- children: renderedRowIndices.map((rowIndex) => {
11498
- const task = tasks[rowIndex];
11499
- if (!task) return null;
11500
- const isParent = parentTaskIds.has(task.id);
11501
- const isHighlighted = filterMode === "highlight" && !!highlightedTaskIds?.has(task.id);
11502
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
11503
- PlanFactRow,
11502
+ children: [
11503
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
11504
+ GridBackground_default,
11504
11505
  {
11505
- task,
11506
- rowIndex,
11507
11506
  dateRange,
11508
- dateKeys,
11509
- renderedDateIndices,
11510
- rowHeight,
11511
- subrowHeight,
11512
11507
  dayWidth,
11513
- plannedRange: plannedRangeByTaskId.get(task.id) ?? null,
11514
- todayDateIndex,
11515
- isParent,
11516
- isHighlighted,
11517
- selectedTaskId,
11518
- activeCell,
11519
- editingCell,
11520
- selectedRange,
11521
- renderedRangeBounds,
11522
- didDragSelectRef,
11523
- isSelectingRef,
11524
- isFillDraggingRef,
11525
- onTaskSelect,
11526
- selectSingleCell,
11527
- queueHoverCellUpdate,
11528
- setActiveCell,
11529
- setEditingCell,
11530
- setFillRange,
11531
- clearSelectedCells,
11532
- commitCell,
11533
- commitSelectedCells,
11534
- moveActiveCell,
11535
- extendSelectedRange,
11536
- focusCell,
11537
- showOverflowTooltip,
11538
- hideOverflowTooltip
11539
- },
11540
- task.id
11541
- );
11542
- })
11508
+ totalHeight: tasks.length * rowHeight,
11509
+ viewMode: "day",
11510
+ isCustomWeekend,
11511
+ showGridLines: false
11512
+ }
11513
+ ),
11514
+ renderedRowIndices.map((rowIndex) => {
11515
+ const task = tasks[rowIndex];
11516
+ if (!task) return null;
11517
+ const isParent = parentTaskIds.has(task.id);
11518
+ const isHighlighted = filterMode === "highlight" && !!highlightedTaskIds?.has(task.id);
11519
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
11520
+ PlanFactRow,
11521
+ {
11522
+ task,
11523
+ rowIndex,
11524
+ dateRange,
11525
+ dateKeys,
11526
+ renderedDateIndices,
11527
+ rowHeight,
11528
+ subrowHeight,
11529
+ dayWidth,
11530
+ plannedRange: plannedRangeByTaskId.get(task.id) ?? null,
11531
+ todayDateIndex,
11532
+ isParent,
11533
+ isHighlighted,
11534
+ selectedTaskId,
11535
+ activeCell,
11536
+ editingCell,
11537
+ selectedRange,
11538
+ renderedRangeBounds,
11539
+ didDragSelectRef,
11540
+ isSelectingRef,
11541
+ isFillDraggingRef,
11542
+ onTaskSelect,
11543
+ selectSingleCell,
11544
+ queueHoverCellUpdate,
11545
+ setActiveCell,
11546
+ setEditingCell,
11547
+ setFillRange,
11548
+ clearSelectedCells,
11549
+ commitCell,
11550
+ commitSelectedCells,
11551
+ moveActiveCell,
11552
+ extendSelectedRange,
11553
+ focusCell,
11554
+ showOverflowTooltip,
11555
+ hideOverflowTooltip
11556
+ },
11557
+ task.id
11558
+ );
11559
+ })
11560
+ ]
11543
11561
  }
11544
11562
  ),
11545
11563
  overflowTooltip && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
@@ -11973,6 +11991,17 @@ var SCROLL_TO_ROW_CONTEXT_ROWS = 2;
11973
11991
  var TASK_ROW_OVERSCAN = 8;
11974
11992
  var PLAN_FACT_COLUMN_OVERSCAN = 24;
11975
11993
  var PLAN_FACT_COLUMN_WINDOW_STEP = 14;
11994
+ function waitForNextPaint2(win) {
11995
+ return new Promise((resolve) => {
11996
+ if (typeof win.requestAnimationFrame === "function") {
11997
+ win.requestAnimationFrame(() => {
11998
+ win.requestAnimationFrame(() => resolve());
11999
+ });
12000
+ return;
12001
+ }
12002
+ win.setTimeout(() => resolve(), 50);
12003
+ });
12004
+ }
11976
12005
  function getFullMonthDays(tasks) {
11977
12006
  if (!tasks || tasks.length === 0) {
11978
12007
  return getMultiMonthDays(tasks);
@@ -12121,9 +12150,9 @@ function TaskGanttChartInner(props, ref) {
12121
12150
  } = props;
12122
12151
  const dayWidth = !isTableMatrixMode ? props.dayWidth ?? 40 : 40;
12123
12152
  const viewMode = !isTableMatrixMode && !isPlanFactMode ? props.viewMode ?? "day" : "day";
12124
- const customDays = !isTableMatrixMode && !isPlanFactMode ? props.customDays : void 0;
12125
- const isWeekend3 = !isTableMatrixMode && !isPlanFactMode ? props.isWeekend : void 0;
12126
- const businessDays = !isTableMatrixMode && !isPlanFactMode ? props.businessDays ?? true : true;
12153
+ const customDays = !isTableMatrixMode ? props.customDays : void 0;
12154
+ const isWeekend3 = !isTableMatrixMode ? props.isWeekend : void 0;
12155
+ const businessDays = !isTableMatrixMode ? props.businessDays ?? true : true;
12127
12156
  const matrixColumns = isTableMatrixMode ? props.matrixColumns : [];
12128
12157
  const matrixColumnGroups = isTableMatrixMode ? props.matrixColumnGroups : void 0;
12129
12158
  const onMatrixCellClick = isTableMatrixMode ? props.onMatrixCellClick : void 0;
@@ -12144,6 +12173,7 @@ function TaskGanttChartInner(props, ref) {
12144
12173
  const [taskListHasRightShadow, setTaskListHasRightShadow] = (0, import_react18.useState)(false);
12145
12174
  const [internalTaskDateChangeMode, setInternalTaskDateChangeMode] = (0, import_react18.useState)("preserve-duration");
12146
12175
  const [scrollViewport, setScrollViewport] = (0, import_react18.useState)({ scrollTop: 0, viewportHeight: 0 });
12176
+ const [forceFullRenderForPrint, setForceFullRenderForPrint] = (0, import_react18.useState)(false);
12147
12177
  const [planFactDateWindow, setPlanFactDateWindow] = (0, import_react18.useState)(null);
12148
12178
  const [selectedChip, setSelectedChip] = (0, import_react18.useState)(null);
12149
12179
  const [activeTimelineTooltip, setActiveTimelineTooltip] = (0, import_react18.useState)(null);
@@ -12555,6 +12585,9 @@ function TaskGanttChartInner(props, ref) {
12555
12585
  if (totalTasks === 0) {
12556
12586
  return [];
12557
12587
  }
12588
+ if (forceFullRenderForPrint) {
12589
+ return Array.from({ length: totalTasks }, (_, index) => index);
12590
+ }
12558
12591
  if (scrollViewport.viewportHeight <= 0) {
12559
12592
  return Array.from({ length: totalTasks }, (_, index) => index);
12560
12593
  }
@@ -12575,8 +12608,11 @@ function TaskGanttChartInner(props, ref) {
12575
12608
  }
12576
12609
  }
12577
12610
  return Array.from(indices).sort((left, right) => left - right);
12578
- }, [effectiveRowHeight, forcedRenderedTaskIds, scrollViewport, visibleTaskIndexMap, visibleTasks.length]);
12611
+ }, [effectiveRowHeight, forceFullRenderForPrint, forcedRenderedTaskIds, scrollViewport, visibleTaskIndexMap, visibleTasks.length]);
12579
12612
  const visiblePlanFactDateIndices = (0, import_react18.useMemo)(() => {
12613
+ if (forceFullRenderForPrint) {
12614
+ return void 0;
12615
+ }
12580
12616
  if (!isPlanFactMode || dateRange.length === 0 || !planFactDateWindow) {
12581
12617
  return void 0;
12582
12618
  }
@@ -12584,7 +12620,7 @@ function TaskGanttChartInner(props, ref) {
12584
12620
  { length: planFactDateWindow.end - planFactDateWindow.start + 1 },
12585
12621
  (_, index) => planFactDateWindow.start + index
12586
12622
  );
12587
- }, [dateRange.length, isPlanFactMode, planFactDateWindow]);
12623
+ }, [dateRange.length, forceFullRenderForPrint, isPlanFactMode, planFactDateWindow]);
12588
12624
  const renderedChartTasks = (0, import_react18.useMemo)(
12589
12625
  () => visibleTaskWindowIndices.map((index) => {
12590
12626
  const task = previewVisibleTasks[index];
@@ -12672,8 +12708,7 @@ function TaskGanttChartInner(props, ref) {
12672
12708
  }, [externalCollapsedParentIds]);
12673
12709
  const exportToPdf = (0, import_react18.useCallback)(async (options) => {
12674
12710
  const sourceContainer = containerRef.current;
12675
- const sourceContent = scrollContentRef.current;
12676
- if (!sourceContainer || !sourceContent || typeof window === "undefined" || typeof document === "undefined") {
12711
+ if (!sourceContainer || typeof window === "undefined" || typeof document === "undefined") {
12677
12712
  return;
12678
12713
  }
12679
12714
  const includeTaskList = options?.includeTaskList ?? showTaskList;
@@ -12681,31 +12716,46 @@ function TaskGanttChartInner(props, ref) {
12681
12716
  if (!includeTaskList && !includeChart) {
12682
12717
  return;
12683
12718
  }
12684
- const printContent = sourceContent.cloneNode(true);
12685
- const taskListClone = printContent.querySelector(".gantt-tl-overlay");
12686
- const chartClone = printContent.querySelector(".gantt-chartSurface");
12687
- if (includeTaskList) {
12688
- taskListClone?.classList.remove("gantt-tl-hidden", "gantt-tl-overlay-shadowed");
12689
- } else {
12690
- taskListClone?.remove();
12719
+ const shouldForceFullRender = !isTableMatrixMode;
12720
+ try {
12721
+ if (shouldForceFullRender) {
12722
+ setForceFullRenderForPrint(true);
12723
+ await waitForNextPaint2(window);
12724
+ }
12725
+ const sourceContent = scrollContentRef.current;
12726
+ if (!sourceContent) {
12727
+ return;
12728
+ }
12729
+ const printContent = sourceContent.cloneNode(true);
12730
+ const taskListClone = printContent.querySelector(".gantt-tl-overlay");
12731
+ const chartClone = printContent.querySelector(".gantt-chartSurface");
12732
+ if (includeTaskList) {
12733
+ taskListClone?.classList.remove("gantt-tl-hidden", "gantt-tl-overlay-shadowed");
12734
+ } else {
12735
+ taskListClone?.remove();
12736
+ }
12737
+ if (includeChart) {
12738
+ chartClone?.classList.remove("gantt-chart-hidden");
12739
+ if (chartClone) chartClone.style.display = "";
12740
+ } else {
12741
+ chartClone?.remove();
12742
+ }
12743
+ await printGanttChart({
12744
+ sourceDocument: document,
12745
+ sourceContainer,
12746
+ printContent,
12747
+ header: options?.header,
12748
+ documentTitle: options?.documentTitle,
12749
+ title: options?.title,
12750
+ fileName: options?.fileName,
12751
+ orientation: options?.orientation
12752
+ });
12753
+ } finally {
12754
+ if (shouldForceFullRender) {
12755
+ setForceFullRenderForPrint(false);
12756
+ }
12691
12757
  }
12692
- if (includeChart) {
12693
- chartClone?.classList.remove("gantt-chart-hidden");
12694
- if (chartClone) chartClone.style.display = "";
12695
- } else {
12696
- chartClone?.remove();
12697
- }
12698
- await printGanttChart({
12699
- sourceDocument: document,
12700
- sourceContainer,
12701
- printContent,
12702
- header: options?.header,
12703
- documentTitle: options?.documentTitle,
12704
- title: options?.title,
12705
- fileName: options?.fileName,
12706
- orientation: options?.orientation
12707
- });
12708
- }, [showTaskList, showChart]);
12758
+ }, [isTableMatrixMode, showTaskList, showChart]);
12709
12759
  (0, import_react18.useImperativeHandle)(
12710
12760
  ref,
12711
12761
  () => ({
@@ -13013,7 +13063,8 @@ function TaskGanttChartInner(props, ref) {
13013
13063
  filterMode,
13014
13064
  visibleRowIndices: visibleTaskWindowIndices,
13015
13065
  visibleDateIndices: visiblePlanFactDateIndices,
13016
- todayDateIndex: todayInRange ? todayIndex : void 0
13066
+ todayDateIndex: todayInRange ? todayIndex : void 0,
13067
+ isCustomWeekend
13017
13068
  }
13018
13069
  ) : /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
13019
13070
  /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(