From 36cb93ecdd8614500953a9100908173fa7f60bf8 Mon Sep 17 00:00:00 2001 From: hsiegeln <37154749+hsiegeln@users.noreply.github.com> Date: Wed, 22 Apr 2026 17:51:58 +0200 Subject: [PATCH] =?UTF-8?q?ui(alerts):=20ExchangeMatchForm=20=E2=80=94=20e?= =?UTF-8?q?nforce=20PER=5FEXCHANGE=20UI=20constraints?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Disable reNotifyMinutes at 0 with tooltip when PER_EXCHANGE is selected (server rejects non-zero per Task 3.3 validator). Hide forDurationSeconds entirely for PER_EXCHANGE (not applicable to per-exchange semantics). Values stay zeroed via Task 4.3's applyFireModeChange helper on any mode toggle. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../pages/Alerts/RuleEditor/TriggerStep.tsx | 31 ++++++++++++++----- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/ui/src/pages/Alerts/RuleEditor/TriggerStep.tsx b/ui/src/pages/Alerts/RuleEditor/TriggerStep.tsx index 61572e9a..9cb874d9 100644 --- a/ui/src/pages/Alerts/RuleEditor/TriggerStep.tsx +++ b/ui/src/pages/Alerts/RuleEditor/TriggerStep.tsx @@ -17,6 +17,13 @@ export function TriggerStep({ const { toast } = useToast(); const [lastResult, setLastResult] = useState(null); + // PER_EXCHANGE fires exactly once per exchange (Task 3.3 server validator + // rejects non-zero reNotifyMinutes / forDurationSeconds for this mode). + // Gate the two inputs here so users can't type values the server will reject. + const isPerExchange = + form.conditionKind === 'EXCHANGE_MATCH' && + (form.condition as Record).fireMode === 'PER_EXCHANGE'; + const onTest = async () => { if (!ruleId) { toast({ title: 'Save rule first to run test evaluate', variant: 'error' }); @@ -40,20 +47,28 @@ export function TriggerStep({ onChange={(e) => setForm({ ...form, evaluationIntervalSeconds: Number(e.target.value) })} /> - - setForm({ ...form, forDurationSeconds: Number(e.target.value) })} - /> - + {!isPerExchange && ( + + setForm({ ...form, forDurationSeconds: Number(e.target.value) })} + /> + + )} setForm({ ...form, reNotifyMinutes: Number(e.target.value) })} + disabled={isPerExchange} + title={ + isPerExchange + ? 'Per-exchange rules fire exactly once per exchange — re-notify does not apply.' + : undefined + } />