move toggle on general page

This commit is contained in:
miloschwartz
2026-06-06 15:34:34 -07:00
parent 7b1f8d98f3
commit aa47f522ef
5 changed files with 136 additions and 103 deletions

View File

@@ -843,6 +843,10 @@
"policyAuthHeaderAuthSummary": "Header configured", "policyAuthHeaderAuthSummary": "Header configured",
"policyAuthHeaderName": "Header name", "policyAuthHeaderName": "Header name",
"policyAuthHeaderValue": "Expected value", "policyAuthHeaderValue": "Expected value",
"policyAuthSetPasscode": "Set Passcode",
"policyAuthSetPincode": "Set PIN Code",
"policyAuthSetEmailWhitelist": "Set Email Whitelist",
"policyAuthSetHeaderAuth": "Set Basic Header Auth",
"policyAccessRulesTitle": "Access Rules", "policyAccessRulesTitle": "Access Rules",
"policyAccessRulesEnableDescription": "When enabled, rules are evaluated in descending order until one evaluates as true.", "policyAccessRulesEnableDescription": "When enabled, rules are evaluated in descending order until one evaluates as true.",
"policyAccessRulesFirstMatch": "Rules are evaluated top to bottom. The first matching rule decides the outcome.", "policyAccessRulesFirstMatch": "Rules are evaluated top to bottom. The first matching rule decides the outcome.",
@@ -3131,6 +3135,7 @@
"maintenanceModeType": "Maintenance Mode Type", "maintenanceModeType": "Maintenance Mode Type",
"showMaintenancePage": "Show a maintenance page to visitors", "showMaintenancePage": "Show a maintenance page to visitors",
"enableMaintenanceMode": "Enable Maintenance Mode", "enableMaintenanceMode": "Enable Maintenance Mode",
"enableMaintenanceModeDescription": "When enabled, visitors will see a maintenance page instead of your resource.",
"automatic": "Automatic", "automatic": "Automatic",
"automaticModeDescription": " Show maintenance page only when all backend targets are down or unhealthy. Your resource continues working normally as long as at least one target is healthy.", "automaticModeDescription": " Show maintenance page only when all backend targets are down or unhealthy. Your resource continues working normally as long as at least one target is healthy.",
"forced": "Forced", "forced": "Forced",

View File

@@ -220,6 +220,11 @@ function MaintenanceSectionForm({
</TooltipProvider> </TooltipProvider>
</FormControl> </FormControl>
</div> </div>
<FormDescription>
{t(
"enableMaintenanceModeDescription"
)}
</FormDescription>
<FormMessage /> <FormMessage />
</FormItem> </FormItem>
); );
@@ -586,6 +591,40 @@ export default function GeneralForm() {
className="space-y-4" className="space-y-4"
id="general-settings-form" id="general-settings-form"
> >
<FormField
control={form.control}
name="enabled"
render={() => (
<FormItem>
<FormControl>
<SwitchInput
id="enable-resource"
defaultChecked={
resource.enabled
}
label={t(
"resourceEnable"
)}
onCheckedChange={(
val
) =>
form.setValue(
"enabled",
val
)
}
/>
</FormControl>
<FormDescription>
{t(
"disabledResourceDescription"
)}
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<div className="grid grid-cols-2 gap-4"> <div className="grid grid-cols-2 gap-4">
<FormField <FormField
control={form.control} control={form.control}
@@ -732,40 +771,6 @@ export default function GeneralForm() {
</div> </div>
</div> </div>
)} )}
<FormField
control={form.control}
name="enabled"
render={() => (
<FormItem>
<FormControl>
<SwitchInput
id="enable-resource"
defaultChecked={
resource.enabled
}
label={t(
"resourceEnable"
)}
onCheckedChange={(
val
) =>
form.setValue(
"enabled",
val
)
}
/>
</FormControl>
<FormDescription>
{t(
"disabledResourceDescription"
)}
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
</form> </form>
</Form> </Form>
</SettingsSectionForm> </SettingsSectionForm>

View File

@@ -117,7 +117,7 @@ export function PasscodeCredenza({
title={t("resourcePasswordSetupTitle")} title={t("resourcePasswordSetupTitle")}
description={t("resourcePasswordSetupTitleDescription")} description={t("resourcePasswordSetupTitleDescription")}
formId="policy-passcode-form" formId="policy-passcode-form"
submitLabel={t("resourcePasswordSubmit")} submitLabel={t("policyAuthSetPasscode")}
> >
<Form {...form}> <Form {...form}>
<form <form
@@ -191,7 +191,7 @@ export function PincodeCredenza({
title={t("resourcePincodeSetupTitle")} title={t("resourcePincodeSetupTitle")}
description={t("resourcePincodeSetupTitleDescription")} description={t("resourcePincodeSetupTitleDescription")}
formId="policy-pincode-form" formId="policy-pincode-form"
submitLabel={t("resourcePincodeSubmit")} submitLabel={t("policyAuthSetPincode")}
> >
<Form {...form}> <Form {...form}>
<form <form
@@ -286,7 +286,7 @@ export function HeaderAuthCredenza({
title={t("resourceHeaderAuthSetupTitle")} title={t("resourceHeaderAuthSetupTitle")}
description={t("resourceHeaderAuthSetupTitleDescription")} description={t("resourceHeaderAuthSetupTitleDescription")}
formId="policy-header-auth-form" formId="policy-header-auth-form"
submitLabel={t("resourceHeaderAuthSubmit")} submitLabel={t("policyAuthSetHeaderAuth")}
> >
<Form {...form}> <Form {...form}>
<form <form
@@ -368,7 +368,7 @@ type EmailCredenzaProps = {
emailEnabled: boolean; emailEnabled: boolean;
disabled?: boolean; disabled?: boolean;
emails: Tag[]; emails: Tag[];
onEmailsChange: (emails: Tag[]) => void; onSave: (emails: Tag[]) => void;
}; };
export function EmailCredenza({ export function EmailCredenza({
@@ -377,12 +377,19 @@ export function EmailCredenza({
emailEnabled, emailEnabled,
disabled, disabled,
emails, emails,
onEmailsChange onSave
}: EmailCredenzaProps) { }: EmailCredenzaProps) {
const t = useTranslations(); const t = useTranslations();
const [activeEmailTagIndex, setActiveEmailTagIndex] = useState< const [activeEmailTagIndex, setActiveEmailTagIndex] = useState<
number | null number | null
>(null); >(null);
const [draftEmails, setDraftEmails] = useState<Tag[]>(emails);
useEffect(() => {
if (open) {
setDraftEmails(emails);
}
}, [open, emails]);
return ( return (
<Credenza open={open} onOpenChange={onOpenChange}> <Credenza open={open} onOpenChange={onOpenChange}>
@@ -394,72 +401,90 @@ export function EmailCredenza({
</CredenzaDescription> </CredenzaDescription>
</CredenzaHeader> </CredenzaHeader>
<CredenzaBody> <CredenzaBody>
<div className="space-y-4"> <form
{!emailEnabled && ( id="policy-email-form"
<Alert variant="neutral"> onSubmit={(event) => {
<InfoIcon className="h-4 w-4" /> event.preventDefault();
<AlertTitle className="font-semibold"> onSave(draftEmails);
{t("otpEmailSmtpRequired")} onOpenChange(false);
</AlertTitle> }}
<AlertDescription> >
{t("otpEmailSmtpRequiredDescription")} <div className="space-y-4">
</AlertDescription> {!emailEnabled && (
</Alert> <Alert variant="neutral">
)} <InfoIcon className="h-4 w-4" />
{emailEnabled && ( <AlertTitle className="font-semibold">
<p className="text-sm text-muted-foreground"> {t("otpEmailSmtpRequired")}
{t("otpEmailWhitelistListDescription")} </AlertTitle>
</p> <AlertDescription>
)} {t("otpEmailSmtpRequiredDescription")}
{emailEnabled && ( </AlertDescription>
<FormItem> </Alert>
<FormLabel> )}
{t("otpEmailWhitelistList")} {emailEnabled && (
</FormLabel> <p className="text-sm text-muted-foreground">
<FormControl> {t("otpEmailWhitelistListDescription")}
<TagInput </p>
activeTagIndex={activeEmailTagIndex} )}
setActiveTagIndex={ {emailEnabled && (
setActiveEmailTagIndex <FormItem>
} <FormLabel>
placeholder={t("otpEmailEnter")} {t("otpEmailWhitelistList")}
tags={emails} </FormLabel>
setTags={(newEmails) => { <FormControl>
if (!disabled) { <TagInput
onEmailsChange( activeTagIndex={activeEmailTagIndex}
newEmails as Tag[] setActiveTagIndex={
); setActiveEmailTagIndex
} }
}} placeholder={t("otpEmailEnter")}
validateTag={(tag) => tags={draftEmails}
z setTags={(newEmails) => {
.email() if (!disabled) {
.or( setDraftEmails(
z newEmails as Tag[]
.string() );
.regex( }
/^\*@[\w.-]+\.[a-zA-Z]{2,}$/ }}
) validateTag={(tag) =>
) z
.safeParse(tag).success .email()
} .or(
allowDuplicates={false} z
sortTags .string()
size="sm" .regex(
disabled={disabled} /^\*@[\w.-]+\.[a-zA-Z]{2,}$/
/> )
</FormControl> )
<FormDescription> .safeParse(tag).success
{t("otpEmailEnterDescription")} }
</FormDescription> allowDuplicates={false}
</FormItem> sortTags
)} size="sm"
</div> disabled={disabled}
/>
</FormControl>
<FormDescription>
{t("otpEmailEnterDescription")}
</FormDescription>
</FormItem>
)}
</div>
</form>
</CredenzaBody> </CredenzaBody>
<CredenzaFooter> <CredenzaFooter>
<CredenzaClose asChild> <CredenzaClose asChild>
<Button variant="outline">{t("close")}</Button> <Button variant="outline">{t("close")}</Button>
</CredenzaClose> </CredenzaClose>
{emailEnabled && (
<Button
type="submit"
form="policy-email-form"
disabled={disabled}
>
{t("policyAuthSetEmailWhitelist")}
</Button>
)}
</CredenzaFooter> </CredenzaFooter>
</CredenzaContent> </CredenzaContent>
</Credenza> </Credenza>

View File

@@ -279,7 +279,7 @@ export function PolicyAuthStackSectionCreate({
onOpenChange={(open) => !open && closeCredenza()} onOpenChange={(open) => !open && closeCredenza()}
emailEnabled={emailEnabled} emailEnabled={emailEnabled}
emails={emails} emails={emails}
onEmailsChange={(value) => onSave={(value) =>
parentForm.setValue( parentForm.setValue(
"emails", "emails",
value as PolicyFormValues["emails"] value as PolicyFormValues["emails"]

View File

@@ -648,9 +648,7 @@ export function PolicyAuthStackSectionEdit({
emailEnabled={emailEnabled} emailEnabled={emailEnabled}
disabled={authReadonly} disabled={authReadonly}
emails={emails} emails={emails}
onEmailsChange={(value) => onSave={(value) => form.setValue("emails", value)}
form.setValue("emails", value)
}
/> />
<HeaderAuthCredenza <HeaderAuthCredenza