All files / src/components/display SessionAttemptSelector.tsx

0% Statements 0/7
0% Branches 0/16
0% Functions 0/3
0% Lines 0/7

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 56 57 58                                                                                                                   
import type { JSX } from "react";
import type { Session } from "../../hooks/types.js";
import styles from "./SessionAttemptSelector.module.scss";
 
/** Props for {@link SessionAttemptSelector}. */
export interface SessionAttemptSelectorProps {
  /** All sessions (attempts) for a task, ordered chronologically. */
  taskSessions: Session[];
  /** The currently selected session id. */
  selectedSessionId: string | undefined;
  /** Called when the user clicks an attempt button. */
  onSelect: (sessionId: string) => void;
}
 
/**
 * Displays a row of numbered attempt buttons when a task has multiple sessions.
 * Returns `undefined` when fewer than two sessions exist.
 */
export function SessionAttemptSelector({
  taskSessions,
  selectedSessionId,
  onSelect,
}: SessionAttemptSelectorProps): JSX.Element | undefined {
  if (taskSessions.length < 2) {
    return undefined;
  }
  return (
    <div className={styles.attemptSelector} data-testid="attempt-selector">
      <span className={styles.attemptLabel}>Attempts:</span>
      {taskSessions.map((s, i) => {
        const isActive = s.id === selectedSessionId;
        const statusIcon =
          s.status === "stopped" && s.endReason === "completed"
            ? "\u2713"
            : s.status === "stopped"
              ? "\u2717"
              : s.status === "running" || s.status === "idle"
                ? "\u25CF"
                : "";
        return (
          <button
            key={s.id}
            className={`${styles.attemptButton} ${isActive ? styles.attemptActive : ""}`}
            onClick={() => onSelect(s.id)}
            title={`Attempt #${i + 1} \u2014 ${s.status}`}
            aria-label={`Attempt #${i + 1}, ${s.status}`}
            aria-pressed={isActive}
            data-testid={`attempt-${i + 1}`}
          >
            #{i + 1}
            {statusIcon && <span className={styles.attemptStatus}>{statusIcon}</span>}
          </button>
        );
      })}
    </div>
  );
}