loops wizard: expose 'until' repeat policy
Third radio option on the repeat step. Two inputs: event name (defaults
to 'ok') and a within_iters cap (defaults to 20). Ships the full
{kind: 'until', event, within_iters} payload the schema already accepts.
LoopsCanvas repeat summary now formats iters/until/infinite via one
helper — the previous inline expression was rendering 'until' as a bare
label with no event context.
This commit is contained in:
@@ -36,8 +36,12 @@ export function LoopsWizard({
|
||||
const [cron, setCron] = useState("0 */6 * * *");
|
||||
const [onCompletion, setOnCompletion] = useState(false);
|
||||
const [webhookEnabled, setWebhookEnabled] = useState(false);
|
||||
const [repeatKind, setRepeatKind] = useState<"infinite" | "iters">("infinite");
|
||||
const [repeatKind, setRepeatKind] = useState<"infinite" | "iters" | "until">(
|
||||
"infinite",
|
||||
);
|
||||
const [iters, setIters] = useState(10);
|
||||
const [untilEvent, setUntilEvent] = useState("ok");
|
||||
const [untilWithin, setUntilWithin] = useState(20);
|
||||
const [submitting, setSubmitting] = useState(false);
|
||||
const [submitError, setSubmitError] = useState<string | null>(null);
|
||||
const [created, setCreated] = useState<LoopCreated | null>(null);
|
||||
@@ -60,10 +64,24 @@ export function LoopsWizard({
|
||||
setSubmitting(false);
|
||||
return;
|
||||
}
|
||||
const repeat_policy: LoopRepeatPolicy =
|
||||
repeatKind === "infinite"
|
||||
? { kind: "infinite" }
|
||||
: { kind: "iters", n: Math.max(1, Math.floor(iters)) };
|
||||
let repeat_policy: LoopRepeatPolicy;
|
||||
if (repeatKind === "infinite") {
|
||||
repeat_policy = { kind: "infinite" };
|
||||
} else if (repeatKind === "iters") {
|
||||
repeat_policy = { kind: "iters", n: Math.max(1, Math.floor(iters)) };
|
||||
} else {
|
||||
const event = untilEvent.trim();
|
||||
if (!event) {
|
||||
setSubmitError("Until: event name is required");
|
||||
setSubmitting(false);
|
||||
return;
|
||||
}
|
||||
repeat_policy = {
|
||||
kind: "until",
|
||||
event,
|
||||
within_iters: Math.max(1, Math.floor(untilWithin)),
|
||||
};
|
||||
}
|
||||
const out = await createLoop({
|
||||
title: title.trim(),
|
||||
description: description.trim(),
|
||||
@@ -260,6 +278,69 @@ export function LoopsWizard({
|
||||
/>
|
||||
)}
|
||||
</label>
|
||||
<label style={radioRowStyle(repeatKind === "until")}>
|
||||
<input
|
||||
type="radio"
|
||||
checked={repeatKind === "until"}
|
||||
onChange={() => setRepeatKind("until")}
|
||||
/>
|
||||
<div style={{ flex: 1 }}>
|
||||
<div style={{ fontWeight: 600, color: "#f3f3f5" }}>Until event</div>
|
||||
<div style={hintStyle}>
|
||||
Stop the first time an iteration emits the named run event.
|
||||
Give up after the iteration cap regardless.
|
||||
</div>
|
||||
{repeatKind === "until" && (
|
||||
<div
|
||||
style={{
|
||||
display: "grid",
|
||||
gridTemplateColumns: "1fr 120px",
|
||||
gap: 8,
|
||||
marginTop: 8,
|
||||
}}
|
||||
>
|
||||
<label
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: 4,
|
||||
}}
|
||||
>
|
||||
<span style={{ ...hintStyle, fontSize: 10, letterSpacing: ".1em", textTransform: "uppercase" }}>
|
||||
Event
|
||||
</span>
|
||||
<input
|
||||
type="text"
|
||||
value={untilEvent}
|
||||
placeholder="ok"
|
||||
onChange={(e) => setUntilEvent(e.target.value)}
|
||||
style={fieldStyle}
|
||||
/>
|
||||
</label>
|
||||
<label
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: 4,
|
||||
}}
|
||||
>
|
||||
<span style={{ ...hintStyle, fontSize: 10, letterSpacing: ".1em", textTransform: "uppercase" }}>
|
||||
Cap
|
||||
</span>
|
||||
<input
|
||||
type="number"
|
||||
value={untilWithin}
|
||||
min={1}
|
||||
onChange={(e) =>
|
||||
setUntilWithin(parseInt(e.target.value, 10) || 1)
|
||||
}
|
||||
style={fieldStyle}
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</label>
|
||||
{submitError && (
|
||||
<p style={{ fontFamily: mono, fontSize: 12, color: "#ff8a7a" }}>
|
||||
{submitError}
|
||||
|
||||
Reference in New Issue
Block a user