Add failover setting step controls
Build and Deploy Gateway / build-and-push (push) Successful in 26s
Build and Deploy Gateway / deploy (push) Successful in 7s

This commit is contained in:
2026-08-20 01:55:50 +03:00
parent c27c898ad5
commit 1ee453b3b6
6 changed files with 43 additions and 27 deletions
+12 -5
View File
@@ -76,17 +76,19 @@ function pulseNumber(event: FormEvent<HTMLInputElement>) {
], { duration: 320, easing: 'cubic-bezier(0.16, 1, 0.3, 1)' });
}
function FailoverNumberSetting({ before, after, value, min, max, disabled, ariaLabel, onChange }: {
function FailoverNumberSetting({ before, after, value, min, max, step = 10, disabled, ariaLabel, onChange }: {
before: string;
after: string;
value: number;
min: number;
max: number;
step?: number;
disabled?: boolean;
ariaLabel: string;
onChange: (value: number) => void;
}) {
return <label className="client-failover-number-setting">
const set = (next: number) => onChange(Math.min(max, Math.max(min, next)));
return <div className="client-failover-number-setting">
<span>{before}</span>
<input
className="client-failover-number-input"
@@ -104,7 +106,11 @@ function FailoverNumberSetting({ before, after, value, min, max, disabled, ariaL
}}
/>
<span>{after}</span>
</label>;
<span className="client-failover-number-steps">
<button type="button" aria-label={`${ariaLabel}: уменьшить на ${step}`} disabled={disabled || value <= min} onClick={() => set(value - step)}>{step}</button>
<button type="button" aria-label={`${ariaLabel}: увеличить на ${step}`} disabled={disabled || value >= max} onClick={() => set(value + step)}>+{step}</button>
</span>
</div>;
}
const reasonLabel = (reason: string | null) => ({
@@ -513,6 +519,7 @@ export function FailoverPanel({
after="секунд"
min={2}
max={30}
step={1}
ariaLabel={`Время ожидания ответа: ${service?.label || 'сервис недоступен'}`}
value={seconds(check.timeoutMs)}
disabled={blocked || !draft.enabled}
@@ -587,8 +594,8 @@ export function FailoverPanel({
</header>
<div className="client-failover-protection-options">
<FailoverNumberSetting before="Оставаться на резервном не меньше" after="секунд" min={60} max={86400} ariaLabel="Минимальное время на резервном канале" value={seconds(draft.minimumReserveMs)} disabled={blocked || !draft.enabled} onChange={(value) => update({ minimumReserveMs: value * 1_000 })} />
<FailoverNumberSetting before="Отправлять основной в карантин после" after="повторных сбоев" min={2} max={10} ariaLabel="Количество повторных сбоев" value={draft.flapProtection.count} disabled={blocked || !draft.enabled} onChange={(value) => update({ flapProtection: { ...draft.flapProtection, count: value } })} />
<FailoverNumberSetting before="Считать повторными сбои за последние" after="часов" min={1} max={72} ariaLabel="Период повторных сбоев" value={Math.round(draft.flapProtection.windowMs / 3_600_000)} disabled={blocked || !draft.enabled} onChange={(value) => update({ flapProtection: { ...draft.flapProtection, windowMs: value * 3_600_000 } })} />
<FailoverNumberSetting before="Отправлять основной в карантин после" after="повторных сбоев" min={2} max={10} step={1} ariaLabel="Количество повторных сбоев" value={draft.flapProtection.count} disabled={blocked || !draft.enabled} onChange={(value) => update({ flapProtection: { ...draft.flapProtection, count: value } })} />
<FailoverNumberSetting before="Считать повторными сбои за последние" after="часов" min={1} max={72} step={1} ariaLabel="Период повторных сбоев" value={Math.round(draft.flapProtection.windowMs / 3_600_000)} disabled={blocked || !draft.enabled} onChange={(value) => update({ flapProtection: { ...draft.flapProtection, windowMs: value * 3_600_000 } })} />
<FailoverNumberSetting before="Не возвращаться на основной после карантина" after="минут" min={10} max={10080} ariaLabel="Длительность карантина основного канала" value={Math.round(draft.flapProtection.quarantineMs / 60_000)} disabled={blocked || !draft.enabled} onChange={(value) => update({ flapProtection: { ...draft.flapProtection, quarantineMs: value * 60_000 } })} />
</div>
</section>