Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 25 additions & 23 deletions src/components/EndpointWizard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type {
import type { ScreenProps } from "../handlers/types";
import { coreOptsFromCtx } from "../handlers/utils";
import { Layout } from "./Layout";
import { FormRadioGroup, type FormRadioOption } from "./FormRadioGroup";
import { Stepper, type Step } from "./ui/stepper";
import { TextInput } from "./ui/text-input";
import { Spinner } from "./ui/spinner";
Expand Down Expand Up @@ -254,10 +255,8 @@ function NameStep({
);
}

interface VersionOption {
interface VersionOption extends FormRadioOption {
value: string;
label: string;
detail: string;
}

function VersionStep({
Expand Down Expand Up @@ -285,14 +284,18 @@ function VersionStep({
.map((v) => ({
value: v.harnessVersion ?? "",
label: `version ${v.harnessVersion}`,
detail: `${v.status} · updated ${v.updatedAt?.toISOString().slice(0, 10) ?? ""}`,
description: `${v.status} · updated ${v.updatedAt?.toISOString().slice(0, 10) ?? ""}`,
}))
.sort((a, b) => Number(b.value) - Number(a.value));
// Create mode offers "latest": omitting targetVersion tracks the newest
// version at creation time.
return mode === "create"
? [
{ value: "", label: "latest", detail: "track the most recent version (default)" },
{
value: "",
label: "latest",
description: "track the most recent version (default)",
},
...listed,
]
: listed;
Expand Down Expand Up @@ -322,28 +325,27 @@ function VersionStep({

return (
<Box flexDirection="column">
<Question text="which harness version should this endpoint serve?" />
{versions.isPending ? (
<Spinner label="loading versions…" />
<>
<Question text="which harness version should this endpoint serve?" />
<Spinner label="loading versions…" />
</>
) : versions.isError ? (
<Text color={theme.colors.error}>✗ {(versions.error as Error).message}</Text>
<>
<Question text="which harness version should this endpoint serve?" />
<Text color={theme.colors.error}>✗ {(versions.error as Error).message}</Text>
</>
) : options.length === 0 ? (
<Text color={theme.colors.muted}>this harness has no versions</Text>
<>
<Question text="which harness version should this endpoint serve?" />
<Text color={theme.colors.muted}>this harness has no versions</Text>
</>
) : (
options.map((option, i) => {
const selected = i === index;
return (
<Box key={option.value === "" ? "(latest)" : option.value}>
<Text color={selected ? theme.colors.focus : theme.colors.muted}>
{selected ? "● " : "○ "}
</Text>
<Text bold={selected} color={selected ? theme.colors.focus : theme.colors.text}>
{option.label.padEnd(12)}
</Text>
<Text color={theme.colors.muted}>{option.detail}</Text>
</Box>
);
})
<FormRadioGroup
helpText="which harness version should this endpoint serve?"
options={options}
focusedIndex={index}
/>
)}
</Box>
);
Expand Down
4 changes: 2 additions & 2 deletions src/components/FormRadioGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export interface FormRadioOption {
}

export interface FormRadioGroupProps {
name: string;
name?: string;
helpText: string;
options: FormRadioOption[];
// highlighted/hovered row
Expand All @@ -32,7 +32,7 @@ export function FormRadioGroup({
return (
<Box flexDirection="column">
<Box flexDirection="column">
<Text color={theme.colors.text}>{name}</Text>
{name && <Text color={theme.colors.text}>{name}</Text>}
<Text color={theme.colors.muted}>{helpText}</Text>
</Box>
<Box
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ describe("harness endpoint create wizard", () => {
// Versions listed newest first after the "latest" default.
await waitForText(r.lastFrame, "which harness version should this endpoint serve?");
expect(r.lastFrame()).toContain("● latest");
expect(r.lastFrame()).toContain("│ ● latest");
expect(r.lastFrame()).toContain("version 2");
expect(r.lastFrame()).toContain("version 1");
await r.press("down"); // version 2
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ describe("harness endpoint update wizard", () => {
// The endpoint's current target (version 1) is preselected; no "latest"
// option exists in update mode.
await waitForText(r.lastFrame, "● version 1");
expect(r.lastFrame()).toContain("│ ● version 1");
expect(r.lastFrame()).not.toContain("latest");
await r.press("up"); // version 2 (sorted newest first)
await waitForText(r.lastFrame, "● version 2");
Expand Down
Loading