# All files / src/components/dag TaskNode.tsx

100% Statements 3/3
100% Branches 4/4
100% Functions 1/1
100% Lines 3/3

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47

    25x
    25x

    25x

     import { Handle, Position } from "@xyflow/react";
    import type { NodeProps } from "@xyflow/react";
    import type { TaskNodeData } from "./useDagLayout.js";
    import { getStatusStyle } from "../../utils/taskStatus.js";
    import styles from "./DagView.module.scss";
    import type { JSX } from "react";

    /** Custom React Flow node component rendering a task as a glass card. */
    export function TaskNode({ data }: NodeProps): JSX.Element {
      const { task, childCount, doneChildCount, hasDependencies } = data as TaskNodeData;
      const statusStyle = getStatusStyle(task.status);

      return (
        <div className={styles.taskNode} data-task-id={task.id} data-task-title={task.title}>
          <Handle
            type="target"
            position={Position.Top}
            isConnectable={false}
            className={styles.handle}
          />
          <div className={styles.taskNodeBorder} style={{ backgroundColor: statusStyle.color }} />
          <div className={styles.taskNodeContent}>
            <div className={styles.taskNodeHeader}>
              <span className={styles.taskNodeIcon} style={{ color: statusStyle.color }}>
                {statusStyle.icon}
              </span>
              <span className={styles.taskNodeTitle}>{task.title}</span>
            </div>
            <div className={styles.taskNodeBadges}>
              {childCount > 0 && (
                <span className={styles.childBadge}>
                  {doneChildCount}/{childCount}
                </span>
              )}
              {hasDependencies && <span className={styles.depBadge}>dep</span>}
            </div>
          </div>
          <Handle
            type="source"
            position={Position.Bottom}
            isConnectable={false}
            className={styles.handle}
          />
        </div>
      );
    }