# All files / src/components/streams StreamNode.tsx

87.5% Statements 7/8
75% Branches 6/8
100% Functions 1/1
87.5% Lines 7/8

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
    48
    49
    50
    51
    52
    53
    54
    55

    50x

    50x

    50x
    50x
    10x

    50x

    50x

     import { Handle, Position } from "@xyflow/react";
    import type { NodeProps } from "@xyflow/react";
    import type { JSX } from "react";
    import type { StreamNodeData } from "./useCoordinationLayout.js";
    import styles from "./CoordinationGraph.module.scss";

    /**
     * Custom React Flow node rendering an IPC stream hub (chatroom, channel, or a
     * non-collapsible pipe). Chatrooms get a halo; non-task-owned hubs render
     * dimmed/haloless. Clicking the node selects the stream (opens its detail panel)
     * via {@link CoordinationGraph}.
     */
    export function StreamNode({ data, selected }: NodeProps): JSX.Element {
      const { stream, streamKind, ownership } = data as StreamNodeData;
      const kindClass =
        streamKind === "chatroom"
          ? styles.chatroom
          : streamKind === "pipe"
            ? styles.pipe
            : styles.channel;
      const classNames = [styles.streamNode, kindClass];
      if (ownership.kind !== "task") {
        classNames.push(styles.haloless);
      }
      Iif (selected) {
        classNames.push(styles.selected);
      }

      return (
        <div className={classNames.join(" ")} data-testid={`coordination-node-stream-${stream.id}`}>
          <Handle
            type="target"
            position={Position.Left}
            isConnectable={false}
            className={styles.handle}
          />
          <div className={styles.nodeContent}>
            <div className={styles.nodeHeader}>
              <span className={styles.kindBadge}>{streamKind}</span>
            </div>
            <span className={styles.nodeTitle}>{stream.name}</span>
            <span className={styles.nodeSubtle}>
              {stream.subscriberCount} {stream.subscriberCount === 1 ? "subscriber" : "subscribers"}
            </span>
          </div>
          <Handle
            type="source"
            position={Position.Right}
            isConnectable={false}
            className={styles.handle}
          />
        </div>
      );
    }