63 lines
1.9 KiB
TypeScript
63 lines
1.9 KiB
TypeScript
// <AgentPicker> — pick agents from a grid of cards, each a labelled checkbox
|
|
// with the agent's icon over its name and, when the caller knows it, a state
|
|
// line under that. The broadcast composer and the schedule form share it, so
|
|
// choosing agents looks the same wherever the operator does it. It holds no
|
|
// state: the caller owns the selection and what a toggle does to it.
|
|
import { AgentIcon } from "../AgentIcon.js";
|
|
import "./AgentPicker.css";
|
|
|
|
export interface AgentPickerOption {
|
|
name: string;
|
|
/** A line under the name, such as "running". Omitted: no line. */
|
|
state?: string;
|
|
/** Colours the state line as up. */
|
|
up?: boolean;
|
|
}
|
|
|
|
export function AgentPicker({
|
|
options,
|
|
selected,
|
|
onToggle,
|
|
label = "agents",
|
|
}: {
|
|
options: AgentPickerOption[];
|
|
selected: string[];
|
|
onToggle: (name: string) => void;
|
|
label?: string;
|
|
}) {
|
|
return (
|
|
<ul class="ui-agent-picker" aria-label={label}>
|
|
{options.map((agent) => {
|
|
const on = selected.includes(agent.name);
|
|
return (
|
|
<li key={agent.name}>
|
|
<label
|
|
class={
|
|
"ui-agent-picker-card" + (on ? " ui-agent-picker-card-on" : "")
|
|
}
|
|
>
|
|
<input
|
|
type="checkbox"
|
|
class="ui-agent-picker-check"
|
|
checked={on}
|
|
onChange={() => onToggle(agent.name)}
|
|
/>
|
|
<AgentIcon name={agent.name} />
|
|
<span class="ui-agent-picker-name">{agent.name}</span>
|
|
{agent.state !== undefined ? (
|
|
<span
|
|
class={
|
|
"ui-agent-picker-state" +
|
|
(agent.up ? " ui-agent-picker-state-up" : "")
|
|
}
|
|
>
|
|
{agent.state}
|
|
</span>
|
|
) : null}
|
|
</label>
|
|
</li>
|
|
);
|
|
})}
|
|
</ul>
|
|
);
|
|
}
|