gantt-lib 0.20.0 → 0.22.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
@@ -362,6 +362,7 @@ __export(index_exports, {
362
362
  TaskRow: () => TaskRow_default,
363
363
  TimeScaleHeader: () => TimeScaleHeader_default,
364
364
  TodayIndicator: () => TodayIndicator_default,
365
+ and: () => and,
365
366
  buildAdjacencyList: () => buildAdjacencyList,
366
367
  calculateBezierPath: () => calculateBezierPath,
367
368
  calculateDependencyPath: () => calculateDependencyPath,
@@ -381,6 +382,7 @@ __export(index_exports, {
381
382
  createDateKey: () => createDateKey,
382
383
  detectCycles: () => detectCycles,
383
384
  detectEdgeZone: () => detectEdgeZone,
385
+ expired: () => expired,
384
386
  findParentId: () => findParentId,
385
387
  flattenHierarchy: () => flattenHierarchy,
386
388
  formatDateLabel: () => formatDateLabel,
@@ -398,18 +400,25 @@ __export(index_exports, {
398
400
  getWeekBlocks: () => getWeekBlocks,
399
401
  getWeekSpans: () => getWeekSpans,
400
402
  getYearSpans: () => getYearSpans,
403
+ inDateRange: () => inDateRange,
404
+ isTaskExpired: () => isTaskExpired,
401
405
  isTaskParent: () => isTaskParent,
402
406
  isToday: () => isToday,
403
407
  isWeekend: () => isWeekend,
408
+ nameContains: () => nameContains,
404
409
  normalizeHierarchyTasks: () => normalizeHierarchyTasks,
405
410
  normalizeTaskDates: () => normalizeTaskDates,
411
+ not: () => not,
412
+ or: () => or,
406
413
  parseUTCDate: () => parseUTCDate,
407
414
  pixelsToDate: () => pixelsToDate,
415
+ progressInRange: () => progressInRange,
408
416
  recalculateIncomingLags: () => recalculateIncomingLags,
409
417
  removeDependenciesBetweenTasks: () => removeDependenciesBetweenTasks,
410
418
  universalCascade: () => universalCascade,
411
419
  useTaskDrag: () => useTaskDrag,
412
- validateDependencies: () => validateDependencies
420
+ validateDependencies: () => validateDependencies,
421
+ withoutDeps: () => withoutDeps
413
422
  });
414
423
  module.exports = __toCommonJS(index_exports);
415
424
 
@@ -566,7 +575,7 @@ function getSuccessorChain(draggedTaskId, allTasks, linkTypes = ["FS"]) {
566
575
  }
567
576
  return chain;
568
577
  }
569
- function cascadeByLinks(movedTaskId, newStart, newEnd, allTasks) {
578
+ function cascadeByLinks(movedTaskId, newStart, newEnd, allTasks, skipChildCascade = false) {
570
579
  const taskById = new Map(allTasks.map((t) => [t.id, t]));
571
580
  const updatedDates = /* @__PURE__ */ new Map();
572
581
  updatedDates.set(movedTaskId, { start: newStart, end: newEnd });
@@ -576,27 +585,29 @@ function cascadeByLinks(movedTaskId, newStart, newEnd, allTasks) {
576
585
  while (queue.length > 0) {
577
586
  const currentId = queue.shift();
578
587
  const { start: predStart, end: predEnd } = updatedDates.get(currentId);
579
- const children = getChildren(currentId, allTasks);
580
- for (const child of children) {
581
- if (visited.has(child.id) || child.locked) continue;
582
- const origStart = new Date(child.startDate);
583
- const origEnd = new Date(child.endDate);
584
- const durationMs = origEnd.getTime() - origStart.getTime();
585
- const parentOrig = taskById.get(currentId);
586
- const parentOrigStart = new Date(parentOrig.startDate);
587
- const parentOrigEnd = new Date(parentOrig.endDate);
588
- const parentStartDelta = predStart.getTime() - parentOrigStart.getTime();
589
- const parentEndDelta = predEnd.getTime() - parentOrigEnd.getTime();
590
- const newChildStart = new Date(origStart.getTime() + parentStartDelta);
591
- const newChildEnd = new Date(origEnd.getTime() + parentEndDelta);
592
- visited.add(child.id);
593
- updatedDates.set(child.id, { start: newChildStart, end: newChildEnd });
594
- result.push({
595
- ...child,
596
- startDate: newChildStart.toISOString().split("T")[0],
597
- endDate: newChildEnd.toISOString().split("T")[0]
598
- });
599
- queue.push(child.id);
588
+ if (!skipChildCascade) {
589
+ const children = getChildren(currentId, allTasks);
590
+ for (const child of children) {
591
+ if (visited.has(child.id) || child.locked) continue;
592
+ const origStart = new Date(child.startDate);
593
+ const origEnd = new Date(child.endDate);
594
+ const durationMs = origEnd.getTime() - origStart.getTime();
595
+ const parentOrig = taskById.get(currentId);
596
+ const parentOrigStart = new Date(parentOrig.startDate);
597
+ const parentOrigEnd = new Date(parentOrig.endDate);
598
+ const parentStartDelta = predStart.getTime() - parentOrigStart.getTime();
599
+ const parentEndDelta = predEnd.getTime() - parentOrigEnd.getTime();
600
+ const newChildStart = new Date(origStart.getTime() + parentStartDelta);
601
+ const newChildEnd = new Date(origEnd.getTime() + parentEndDelta);
602
+ visited.add(child.id);
603
+ updatedDates.set(child.id, { start: newChildStart, end: newChildEnd });
604
+ result.push({
605
+ ...child,
606
+ startDate: newChildStart.toISOString().split("T")[0],
607
+ endDate: newChildEnd.toISOString().split("T")[0]
608
+ });
609
+ queue.push(child.id);
610
+ }
600
611
  }
601
612
  for (const task of allTasks) {
602
613
  if (visited.has(task.id) || !task.dependencies || task.locked) continue;
@@ -1327,6 +1338,27 @@ var calculateOrthogonalPath = (from, to) => {
1327
1338
  return `M ${fx} ${fy} H ${tx} V ${ty}`;
1328
1339
  };
1329
1340
 
1341
+ // src/utils/expired.ts
1342
+ init_dateUtils();
1343
+ var isTaskExpired = (task, referenceDate = /* @__PURE__ */ new Date()) => {
1344
+ if (!task) return false;
1345
+ const actualProgress = task.progress ?? 0;
1346
+ if (actualProgress >= 100) return false;
1347
+ const today = new Date(Date.UTC(
1348
+ referenceDate.getFullYear(),
1349
+ referenceDate.getMonth(),
1350
+ referenceDate.getDate()
1351
+ ));
1352
+ const taskStart = parseUTCDate(task.startDate);
1353
+ const taskEnd = parseUTCDate(task.endDate);
1354
+ const msPerDay = 1e3 * 60 * 60 * 24;
1355
+ const duration = taskEnd.getTime() - taskStart.getTime() + msPerDay;
1356
+ const elapsedFromToday = today.getTime() - taskStart.getTime();
1357
+ const elapsed = Math.min(Math.max(0, elapsedFromToday), duration);
1358
+ const expectedProgress = elapsed / duration * 100;
1359
+ return actualProgress < expectedProgress;
1360
+ };
1361
+
1330
1362
  // src/hooks/useTaskDrag.ts
1331
1363
  var import_react2 = require("react");
1332
1364
  var globalActiveDrag = null;
@@ -1749,10 +1781,10 @@ var useTaskDrag = (options) => {
1749
1781
  // src/components/TaskRow/TaskRow.tsx
1750
1782
  var import_jsx_runtime2 = require("react/jsx-runtime");
1751
1783
  var arePropsEqual = (prevProps, nextProps) => {
1752
- 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.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.allTasks === nextProps.allTasks && prevProps.disableConstraints === nextProps.disableConstraints && prevProps.task.locked === nextProps.task.locked && prevProps.task.divider === nextProps.task.divider && prevProps.highlightExpiredTasks === nextProps.highlightExpiredTasks;
1784
+ 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.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.allTasks === nextProps.allTasks && prevProps.disableConstraints === nextProps.disableConstraints && prevProps.task.locked === nextProps.task.locked && prevProps.task.divider === nextProps.task.divider && prevProps.highlightExpiredTasks === nextProps.highlightExpiredTasks && prevProps.isFilterMatch === nextProps.isFilterMatch;
1753
1785
  };
1754
1786
  var TaskRow = import_react3.default.memo(
1755
- ({ task, monthStart, dayWidth, rowHeight, onTasksChange, onDragStateChange, rowIndex, allTasks, enableAutoSchedule, disableConstraints, overridePosition, onCascadeProgress, onCascade, divider, highlightExpiredTasks }) => {
1787
+ ({ task, monthStart, dayWidth, rowHeight, onTasksChange, onDragStateChange, rowIndex, allTasks, enableAutoSchedule, disableConstraints, overridePosition, onCascadeProgress, onCascade, divider, highlightExpiredTasks, isFilterMatch = false }) => {
1756
1788
  const { divider: taskDivider } = task;
1757
1789
  const taskStartDate = (0, import_react3.useMemo)(() => parseUTCDate(task.startDate), [task.startDate]);
1758
1790
  const taskEndDate = (0, import_react3.useMemo)(() => parseUTCDate(task.endDate), [task.endDate]);
@@ -1764,20 +1796,7 @@ var TaskRow = import_react3.default.memo(
1764
1796
  }, [allTasks, task.id]);
1765
1797
  const isExpired = (0, import_react3.useMemo)(() => {
1766
1798
  if (!highlightExpiredTasks) return false;
1767
- const now = /* @__PURE__ */ new Date();
1768
- const today = new Date(Date.UTC(now.getFullYear(), now.getMonth(), now.getDate()));
1769
- const taskStart = parseUTCDate(task.startDate);
1770
- const taskEnd = parseUTCDate(task.endDate);
1771
- const actualProgress = task.progress ?? 0;
1772
- if (actualProgress >= 100) {
1773
- return false;
1774
- }
1775
- const msPerDay = 1e3 * 60 * 60 * 24;
1776
- const duration = taskEnd.getTime() - taskStart.getTime() + msPerDay;
1777
- const elapsedFromToday = today.getTime() - taskStart.getTime();
1778
- const elapsed = Math.min(Math.max(0, elapsedFromToday), duration);
1779
- const expected = elapsed / duration * 100;
1780
- return actualProgress < expected;
1799
+ return isTaskExpired(task);
1781
1800
  }, [task.startDate, task.endDate, task.progress, highlightExpiredTasks]);
1782
1801
  const { left, width } = (0, import_react3.useMemo)(
1783
1802
  () => calculateTaskBar(taskStartDate, taskEndDate, monthStart, dayWidth),
@@ -1862,12 +1881,15 @@ var TaskRow = import_react3.default.memo(
1862
1881
  if (lastDigit >= 2 && lastDigit <= 4) return `${count} \u0437\u0430\u0434\u0430\u0447\u0438`;
1863
1882
  return `${count} \u0437\u0430\u0434\u0430\u0447`;
1864
1883
  };
1865
- const estimatedTextWidth = durationDays >= 10 ? 76 : 62;
1884
+ const estimatedTextWidth = isParent ? 120 : durationDays >= 10 ? 76 : 62;
1866
1885
  const showProgressInside = progressWidth > 0 && displayWidth > estimatedTextWidth;
1886
+ const MIN_DURATION_WIDTH = isParent ? 80 : 50;
1887
+ const showDurationInside = durationDays >= 2 && displayWidth > MIN_DURATION_WIDTH;
1867
1888
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1868
1889
  "div",
1869
1890
  {
1870
- className: "gantt-tr-row",
1891
+ "data-filter-match": isFilterMatch ? "true" : "false",
1892
+ className: `gantt-tr-row ${isFilterMatch ? "gantt-tr-row-filter-match" : ""}`,
1871
1893
  style: { height: `${rowHeight}px` },
1872
1894
  children: [
1873
1895
  taskDivider === "top" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "gantt-tr-divider gantt-tr-divider-top" }),
@@ -1901,7 +1923,7 @@ var TaskRow = import_react3.default.memo(
1901
1923
  }
1902
1924
  ),
1903
1925
  !isParent && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "gantt-tr-resizeHandle gantt-tr-resizeHandleLeft" }),
1904
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "gantt-tr-taskDuration", children: isParent ? getChildCountLabel(childCount) : `${durationDays} \u0434` }),
1926
+ showDurationInside && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "gantt-tr-taskDuration", children: isParent ? getChildCountLabel(childCount) : `${durationDays} \u0434` }),
1905
1927
  progressWidth > 0 && showProgressInside && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "gantt-tr-progressText", children: [
1906
1928
  progressWidth,
1907
1929
  "%"
@@ -1950,9 +1972,10 @@ var TaskRow = import_react3.default.memo(
1950
1972
  {
1951
1973
  className: "gantt-tr-rightLabels",
1952
1974
  style: {
1953
- left: `${displayLeft + displayWidth}px`
1975
+ left: `${displayLeft + Math.max(displayWidth, 20) - Math.min(6, Math.max(displayWidth, 20) / 2) + 8}px`
1954
1976
  },
1955
1977
  children: [
1978
+ !showDurationInside && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "gantt-tr-externalDuration", children: isParent ? getChildCountLabel(childCount) : `${durationDays} \u0434` }),
1956
1979
  progressWidth > 0 && !showProgressInside && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "gantt-tr-externalProgress", children: [
1957
1980
  progressWidth,
1958
1981
  "%"
@@ -3350,7 +3373,8 @@ var TaskListRow = import_react10.default.memo(
3350
3373
  nestingDepth = 0,
3351
3374
  ancestorContinues = [],
3352
3375
  customDays,
3353
- isWeekend: isWeekend3
3376
+ isWeekend: isWeekend3,
3377
+ isFilterMatch = false
3354
3378
  }) => {
3355
3379
  const [editingName, setEditingName] = (0, import_react10.useState)(false);
3356
3380
  const [nameValue, setNameValue] = (0, import_react10.useState)("");
@@ -3749,8 +3773,10 @@ var TaskListRow = import_react10.default.memo(
3749
3773
  return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
3750
3774
  "div",
3751
3775
  {
3776
+ "data-filter-match": isFilterMatch ? "true" : "false",
3752
3777
  className: [
3753
3778
  "gantt-tl-row",
3779
+ isFilterMatch ? "gantt-tl-row-filter-match" : "",
3754
3780
  isSelected ? "gantt-tl-row-selected" : "",
3755
3781
  isPicking && !isSourceRow ? "gantt-tl-row-picking" : "",
3756
3782
  isSourceRow ? "gantt-tl-row-picking-self" : "",
@@ -4088,11 +4114,14 @@ var TaskListRow = import_react10.default.memo(
4088
4114
  ]
4089
4115
  }
4090
4116
  ),
4091
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4117
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
4092
4118
  "span",
4093
4119
  {
4094
4120
  style: editingDuration ? { visibility: "hidden", pointerEvents: "none" } : void 0,
4095
- children: getInclusiveDurationDays(task.startDate, task.endDate)
4121
+ children: [
4122
+ getInclusiveDurationDays(task.startDate, task.endDate),
4123
+ "\u0434"
4124
+ ]
4096
4125
  }
4097
4126
  )
4098
4127
  ]
@@ -4189,7 +4218,7 @@ var TaskListRow = import_react10.default.memo(
4189
4218
  padding: "2px 4px",
4190
4219
  color: "#ffffff"
4191
4220
  } : void 0,
4192
- children: task.progress ? Math.round(task.progress) === 100 ? "100" : `${Math.round(task.progress)}%` : "0%"
4221
+ children: task.progress ? Math.round(task.progress) === 100 ? "100" : `${Math.round(task.progress)}%` : "-"
4193
4222
  }
4194
4223
  )
4195
4224
  ]
@@ -4428,7 +4457,8 @@ var TaskList = ({
4428
4457
  onPromoteTask,
4429
4458
  onDemoteTask,
4430
4459
  customDays,
4431
- isWeekend: isWeekend3
4460
+ isWeekend: isWeekend3,
4461
+ highlightedTaskIds = /* @__PURE__ */ new Set()
4432
4462
  }) => {
4433
4463
  const [internalCollapsedParentIds, setInternalCollapsedParentIds] = (0, import_react12.useState)(/* @__PURE__ */ new Set());
4434
4464
  const collapsedParentIds = externalCollapsedParentIds ?? internalCollapsedParentIds;
@@ -4896,7 +4926,8 @@ var TaskList = ({
4896
4926
  nestingDepth: nestingDepthMap.get(task.id) ?? 0,
4897
4927
  ancestorContinues: ancestorContinuesMap.get(task.id) ?? [],
4898
4928
  customDays,
4899
- isWeekend: isWeekend3
4929
+ isWeekend: isWeekend3,
4930
+ isFilterMatch: highlightedTaskIds.has(task.id)
4900
4931
  },
4901
4932
  task.id
4902
4933
  )) }),
@@ -4966,7 +4997,8 @@ var GanttChart = (0, import_react13.forwardRef)(({
4966
4997
  enableAddTask = true,
4967
4998
  viewMode = "day",
4968
4999
  customDays,
4969
- isWeekend: isWeekend3
5000
+ isWeekend: isWeekend3,
5001
+ taskFilter
4970
5002
  }, ref) => {
4971
5003
  const scrollContainerRef = (0, import_react13.useRef)(null);
4972
5004
  const [selectedTaskId, setSelectedTaskId] = (0, import_react13.useState)(null);
@@ -4986,7 +5018,7 @@ var GanttChart = (0, import_react13.forwardRef)(({
4986
5018
  () => Math.round(dateRange.length * dayWidth),
4987
5019
  [dateRange.length, dayWidth]
4988
5020
  );
4989
- const filteredTasks = (0, import_react13.useMemo)(() => {
5021
+ const visibleTasks = (0, import_react13.useMemo)(() => {
4990
5022
  const parentMap = new Map(normalizedTasks.map((t) => [t.id, t.parentId]));
4991
5023
  function isAnyAncestorCollapsed(parentId) {
4992
5024
  let current = parentId;
@@ -4998,9 +5030,13 @@ var GanttChart = (0, import_react13.forwardRef)(({
4998
5030
  }
4999
5031
  return normalizedTasks.filter((task) => !isAnyAncestorCollapsed(task.parentId));
5000
5032
  }, [normalizedTasks, collapsedParentIds]);
5033
+ const matchedTaskIds = (0, import_react13.useMemo)(() => {
5034
+ if (!taskFilter) return /* @__PURE__ */ new Set();
5035
+ return new Set(visibleTasks.filter(taskFilter).map((task) => task.id));
5036
+ }, [visibleTasks, taskFilter]);
5001
5037
  const totalGridHeight = (0, import_react13.useMemo)(
5002
- () => filteredTasks.length * rowHeight,
5003
- [filteredTasks.length, rowHeight]
5038
+ () => visibleTasks.length * rowHeight,
5039
+ [visibleTasks.length, rowHeight]
5004
5040
  );
5005
5041
  const monthStart = (0, import_react13.useMemo)(() => {
5006
5042
  if (dateRange.length === 0) {
@@ -5116,8 +5152,20 @@ var GanttChart = (0, import_react13.forwardRef)(({
5116
5152
  }
5117
5153
  return;
5118
5154
  }
5119
- const cascadedTasks = disableConstraints ? [updatedTask] : [updatedTask, ...cascadeByLinks(updatedTask.id, newStart, newEnd, tasks)];
5120
- onTasksChange?.(cascadedTasks);
5155
+ const isParent = isTaskParent(updatedTask.id, tasks);
5156
+ if (isParent) {
5157
+ const { startDate: parentStart, endDate: parentEnd } = computeParentDates(updatedTask.id, tasks);
5158
+ const parentWithRecalcDates = {
5159
+ ...updatedTask,
5160
+ startDate: parentStart.toISOString().split("T")[0],
5161
+ endDate: parentEnd.toISOString().split("T")[0]
5162
+ };
5163
+ const cascadedTasks = disableConstraints ? [parentWithRecalcDates] : [parentWithRecalcDates, ...cascadeByLinks(updatedTask.id, parentStart, parentEnd, tasks, true)];
5164
+ onTasksChange?.(cascadedTasks);
5165
+ } else {
5166
+ const cascadedTasks = disableConstraints ? [updatedTask] : [updatedTask, ...cascadeByLinks(updatedTask.id, newStart, newEnd, tasks)];
5167
+ onTasksChange?.(cascadedTasks);
5168
+ }
5121
5169
  }, [tasks, onTasksChange, disableConstraints, editingTaskId]);
5122
5170
  const handleDelete = (0, import_react13.useCallback)((taskId) => {
5123
5171
  const toDelete = /* @__PURE__ */ new Set([taskId]);
@@ -5371,6 +5419,7 @@ var GanttChart = (0, import_react13.forwardRef)(({
5371
5419
  onToggleCollapse: handleToggleCollapse,
5372
5420
  onPromoteTask: onPromoteTask ?? handlePromoteTask,
5373
5421
  onDemoteTask: onDemoteTask ?? handleDemoteTask,
5422
+ highlightedTaskIds: matchedTaskIds,
5374
5423
  customDays,
5375
5424
  isWeekend: isWeekend3
5376
5425
  }
@@ -5409,7 +5458,7 @@ var GanttChart = (0, import_react13.forwardRef)(({
5409
5458
  /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5410
5459
  DependencyLines_default,
5411
5460
  {
5412
- tasks: filteredTasks,
5461
+ tasks: visibleTasks,
5413
5462
  allTasks: normalizedTasks,
5414
5463
  collapsedParentIds,
5415
5464
  monthStart,
@@ -5430,7 +5479,7 @@ var GanttChart = (0, import_react13.forwardRef)(({
5430
5479
  totalHeight: totalGridHeight
5431
5480
  }
5432
5481
  ),
5433
- filteredTasks.map((task, index) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5482
+ visibleTasks.map((task, index) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5434
5483
  TaskRow_default,
5435
5484
  {
5436
5485
  task,
@@ -5454,7 +5503,8 @@ var GanttChart = (0, import_react13.forwardRef)(({
5454
5503
  overridePosition: cascadeOverrides.get(task.id),
5455
5504
  onCascadeProgress: handleCascadeProgress,
5456
5505
  onCascade: handleCascade,
5457
- highlightExpiredTasks
5506
+ highlightExpiredTasks,
5507
+ isFilterMatch: matchedTaskIds.has(task.id)
5458
5508
  },
5459
5509
  task.id
5460
5510
  ))
@@ -5486,6 +5536,32 @@ Button.displayName = "Button";
5486
5536
 
5487
5537
  // src/utils/index.ts
5488
5538
  init_dateUtils();
5539
+
5540
+ // src/filters/index.ts
5541
+ init_dateUtils();
5542
+ var and = (...predicates) => (task) => predicates.every((p) => p(task));
5543
+ var or = (...predicates) => (task) => predicates.some((p) => p(task));
5544
+ var not = (predicate) => (task) => !predicate(task);
5545
+ var withoutDeps = () => (task) => !!task && (!task.dependencies || task.dependencies.length === 0);
5546
+ var expired = (referenceDate = /* @__PURE__ */ new Date()) => (task) => isTaskExpired(task, referenceDate);
5547
+ var inDateRange = (rangeStart, rangeEnd) => (task) => {
5548
+ if (!task) return false;
5549
+ const taskStart = parseUTCDate(task.startDate);
5550
+ const taskEnd = parseUTCDate(task.endDate);
5551
+ return taskStart.getTime() <= rangeEnd.getTime() && taskEnd.getTime() >= rangeStart.getTime();
5552
+ };
5553
+ var progressInRange = (min, max) => (task) => {
5554
+ if (!task) return false;
5555
+ const progress = task.progress ?? 0;
5556
+ return progress >= min && progress <= max;
5557
+ };
5558
+ var nameContains = (substring, caseSensitive = false) => (task) => {
5559
+ if (!task) return false;
5560
+ const name = task.name;
5561
+ const search = caseSensitive ? substring : substring.toLowerCase();
5562
+ const target = caseSensitive ? name : name.toLowerCase();
5563
+ return target.includes(search);
5564
+ };
5489
5565
  // Annotate the CommonJS export names for ESM import in node:
5490
5566
  0 && (module.exports = {
5491
5567
  Button,
@@ -5502,6 +5578,7 @@ init_dateUtils();
5502
5578
  TaskRow,
5503
5579
  TimeScaleHeader,
5504
5580
  TodayIndicator,
5581
+ and,
5505
5582
  buildAdjacencyList,
5506
5583
  calculateBezierPath,
5507
5584
  calculateDependencyPath,
@@ -5521,6 +5598,7 @@ init_dateUtils();
5521
5598
  createDateKey,
5522
5599
  detectCycles,
5523
5600
  detectEdgeZone,
5601
+ expired,
5524
5602
  findParentId,
5525
5603
  flattenHierarchy,
5526
5604
  formatDateLabel,
@@ -5538,17 +5616,24 @@ init_dateUtils();
5538
5616
  getWeekBlocks,
5539
5617
  getWeekSpans,
5540
5618
  getYearSpans,
5619
+ inDateRange,
5620
+ isTaskExpired,
5541
5621
  isTaskParent,
5542
5622
  isToday,
5543
5623
  isWeekend,
5624
+ nameContains,
5544
5625
  normalizeHierarchyTasks,
5545
5626
  normalizeTaskDates,
5627
+ not,
5628
+ or,
5546
5629
  parseUTCDate,
5547
5630
  pixelsToDate,
5631
+ progressInRange,
5548
5632
  recalculateIncomingLags,
5549
5633
  removeDependenciesBetweenTasks,
5550
5634
  universalCascade,
5551
5635
  useTaskDrag,
5552
- validateDependencies
5636
+ validateDependencies,
5637
+ withoutDeps
5553
5638
  });
5554
5639
  //# sourceMappingURL=index.js.map