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,121 +548,85 @@ 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" render={({ field }) => (
render={({ field }) => ( <FormItem>
<FormItem> <FormControl>
<FormControl> <StrategySelect
<StrategySelect cols={2}
cols={2} options={[
options={[ {
{ id: "http",
id: "http", title: "HTTP",
title: "HTTP", description: t(
description: "healthCheckStrategyHttp"
t( )
"healthCheckStrategyHttp" },
) {
}, id: "tcp",
{ title: "TCP",
id: "tcp", description: t(
title: "TCP", "healthCheckStrategyTcp"
description: )
t( },
"healthCheckStrategyTcp" {
) id: "snmp",
}, title: "SNMP",
{ description: t(
id: "snmp", "healthCheckStrategySnmp"
title: "SNMP", )
description: },
t( {
"healthCheckStrategySnmp" id: "icmp",
) title: "Ping (ICMP)",
}, description: t(
{ "healthCheckStrategyIcmp"
id: "icmp",
title: "Ping (ICMP)",
description:
t(
"healthCheckStrategyIcmp"
)
}
]}
value={
field.value
}
onChange={(
value
) =>
handleChange(
"hcMode",
value,
field.onChange
) )
} }
/> ]}
</FormControl> value={field.value}
<FormMessage /> onChange={(value) =>
</FormItem> handleChange(
)} "hcMode",
/> value,
)} field.onChange
)
}
/>
</FormControl>
<FormMessage />
</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>