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                          77x   77x         77x 77x 16x   77x       77x                                                    
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>
  );
}