# All files / src/components/display SessionAttemptSelector.tsx

100% Statements 7/7
86.66% Branches 13/15
100% Functions 3/3
100% Lines 7/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

    10x
    4x

    6x

    14x

    14x

    14x

    1x

     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>
      );
    }