move switch toggle above tabs on health check dialog

This commit is contained in:
miloschwartz
2026-04-25 15:23:22 -07:00
parent 56816c7584
commit 8e16ff07a9
2 changed files with 121 additions and 119 deletions

View File

@@ -1903,6 +1903,7 @@
"configureHealthCheck": "Configure Health Check", "configureHealthCheck": "Configure Health Check",
"configureHealthCheckDescription": "Set up health monitoring for {target}", "configureHealthCheckDescription": "Set up health monitoring for {target}",
"enableHealthChecks": "Enable Health Checks", "enableHealthChecks": "Enable Health Checks",
"healthCheckDisabledStateDescription": "When disabled, the site will not perform health checks and the state will be considered unknown.",
"enableHealthChecksDescription": "Monitor the health of this target. You can monitor a different endpoint than the target if required.", "enableHealthChecksDescription": "Monitor the health of this target. You can monitor a different endpoint than the target if required.",
"healthScheme": "Method", "healthScheme": "Method",
"healthSelectScheme": "Select Method", "healthSelectScheme": "Select Method",

View File

@@ -46,6 +46,7 @@ import { SitesSelector } from "@app/components/site-selector";
import type { Selectedsite } from "@app/components/site-selector"; import type { Selectedsite } from "@app/components/site-selector";
import { CaretSortIcon } from "@radix-ui/react-icons"; import { CaretSortIcon } from "@radix-ui/react-icons";
import { cn } from "@app/lib/cn"; import { cn } from "@app/lib/cn";
import { SwitchInput } from "@app/components/SwitchInput";
export type HealthCheckConfig = { export type HealthCheckConfig = {
hcEnabled: boolean; hcEnabled: boolean;
@@ -407,7 +408,7 @@ export function HealthCheckCredenza(props: HealthCheckCredenzaProps) {
}) })
: t("standaloneHcDescription"); : t("standaloneHcDescription");
const showFields = mode === "submit" || watchedEnabled; const disableTabInputs = mode === "autoSave" && !watchedEnabled;
const isSnmpOrIcmp = watchedMode === "snmp" || watchedMode === "icmp"; const isSnmpOrIcmp = watchedMode === "snmp" || watchedMode === "icmp";
const isTcp = watchedMode === "tcp"; const isTcp = watchedMode === "tcp";
@@ -491,6 +492,40 @@ export function HealthCheckCredenza(props: HealthCheckCredenzaProps) {
</div> </div>
)} )}
{mode === "autoSave" && (
<div className="mt-5">
<FormField
control={form.control}
name="hcEnabled"
render={({ field }) => (
<FormItem>
<FormControl>
<SwitchInput
id="hcEnabled"
label={t(
"enableHealthChecks"
)}
description={t(
"healthCheckDisabledStateDescription"
)}
checked={field.value}
onCheckedChange={(
value
) =>
handleChange(
"hcEnabled",
value,
field.onChange
)
}
/>
</FormControl>
</FormItem>
)}
/>
</div>
)}
<div className="mt-5"> <div className="mt-5">
<HorizontalTabs <HorizontalTabs
clientSide clientSide
@@ -513,44 +548,16 @@ export function HealthCheckCredenza(props: HealthCheckCredenzaProps) {
]} ]}
> >
{/* ── Strategy tab ──────────────────────── */} {/* ── Strategy tab ──────────────────────── */}
<div className="space-y-4 mt-4 p-1"> <div className="mt-4 p-1">
{/* Enable toggle (autoSave mode only) */} <fieldset
{mode === "autoSave" && ( disabled={disableTabInputs}
<FormField className={cn(
control={form.control} "space-y-4",
name="hcEnabled" disableTabInputs &&
render={({ field }) => ( "pointer-events-none opacity-60"
<FormItem className="flex flex-row items-center justify-between rounded-lg border p-4">
<div>
<FormLabel>
{t(
"enableHealthChecks"
)} )}
</FormLabel> >
</div>
<FormControl>
<Switch
checked={
field.value
}
onCheckedChange={(
value
) =>
handleChange(
"hcEnabled",
value,
field.onChange
)
}
/>
</FormControl>
</FormItem>
)}
/>
)}
{/* Strategy picker */} {/* Strategy picker */}
{showFields && (
<FormField <FormField
control={form.control} control={form.control}
name="hcMode" name="hcMode"
@@ -563,42 +570,34 @@ export function HealthCheckCredenza(props: HealthCheckCredenzaProps) {
{ {
id: "http", id: "http",
title: "HTTP", title: "HTTP",
description: description: t(
t(
"healthCheckStrategyHttp" "healthCheckStrategyHttp"
) )
}, },
{ {
id: "tcp", id: "tcp",
title: "TCP", title: "TCP",
description: description: t(
t(
"healthCheckStrategyTcp" "healthCheckStrategyTcp"
) )
}, },
{ {
id: "snmp", id: "snmp",
title: "SNMP", title: "SNMP",
description: description: t(
t(
"healthCheckStrategySnmp" "healthCheckStrategySnmp"
) )
}, },
{ {
id: "icmp", id: "icmp",
title: "Ping (ICMP)", title: "Ping (ICMP)",
description: description: t(
t(
"healthCheckStrategyIcmp" "healthCheckStrategyIcmp"
) )
} }
]} ]}
value={ value={field.value}
field.value onChange={(value) =>
}
onChange={(
value
) =>
handleChange( handleChange(
"hcMode", "hcMode",
value, value,
@@ -611,23 +610,23 @@ export function HealthCheckCredenza(props: HealthCheckCredenzaProps) {
</FormItem> </FormItem>
)} )}
/> />
)} </fieldset>
</div> </div>
{/* ── Connection tab ────────────────────── */} {/* ── Connection tab ────────────────────── */}
<div className="space-y-4 mt-4 p-1"> <div className="mt-4 p-1">
{!showFields && ( <fieldset
<p className="text-sm text-muted-foreground"> disabled={disableTabInputs}
{t("enableHealthChecks")} className={cn(
</p> "space-y-4",
disableTabInputs &&
"pointer-events-none opacity-60"
)} )}
>
{/* Contact-sales banner for SNMP / ICMP */} {/* Contact-sales banner for SNMP / ICMP */}
{showFields && isSnmpOrIcmp && ( {isSnmpOrIcmp && <ContactSalesBanner />}
<ContactSalesBanner />
)}
{showFields && !isSnmpOrIcmp && ( {!isSnmpOrIcmp && (
<> <>
{/* Scheme / Hostname / Port */} {/* Scheme / Hostname / Port */}
{isTcp ? ( {isTcp ? (
@@ -1021,22 +1020,23 @@ export function HealthCheckCredenza(props: HealthCheckCredenzaProps) {
)} )}
</> </>
)} )}
</fieldset>
</div> </div>
{/* ── Advanced tab ──────────────────────── */} {/* ── Advanced tab ──────────────────────── */}
<div className="space-y-4 mt-4 p-1"> <div className="mt-4 p-1">
{!showFields && ( <fieldset
<p className="text-sm text-muted-foreground"> disabled={disableTabInputs}
{t("enableHealthChecks")} className={cn(
</p> "space-y-4",
disableTabInputs &&
"pointer-events-none opacity-60"
)} )}
>
{/* Contact-sales banner for SNMP / ICMP */} {/* Contact-sales banner for SNMP / ICMP */}
{showFields && isSnmpOrIcmp && ( {isSnmpOrIcmp && <ContactSalesBanner />}
<ContactSalesBanner />
)}
{showFields && !isSnmpOrIcmp && ( {!isSnmpOrIcmp && (
<> <>
{/* Healthy interval + threshold */} {/* Healthy interval + threshold */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-4"> <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
@@ -1350,6 +1350,7 @@ export function HealthCheckCredenza(props: HealthCheckCredenzaProps) {
)} )}
</> </>
)} )}
</fieldset>
</div> </div>
</HorizontalTabs> </HorizontalTabs>
</div> </div>