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",
"policyAuthHeaderName": "Header name",
"policyAuthHeaderValue": "Expected value",
"policyAuthSetPasscode": "Set Passcode",
"policyAuthSetPincode": "Set PIN Code",
"policyAuthSetEmailWhitelist": "Set Email Whitelist",
"policyAuthSetHeaderAuth": "Set Basic Header Auth",
"policyAccessRulesTitle": "Access Rules",
"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.",
@@ -3131,6 +3135,7 @@
"maintenanceModeType": "Maintenance Mode Type",
"showMaintenancePage": "Show a maintenance page to visitors",
"enableMaintenanceMode": "Enable Maintenance Mode",
"enableMaintenanceModeDescription": "When enabled, visitors will see a maintenance page instead of your resource.",
"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.",
"forced": "Forced",

View File

@@ -220,6 +220,11 @@ function MaintenanceSectionForm({
</TooltipProvider>
</FormControl>
</div>
<FormDescription>
{t(
"enableMaintenanceModeDescription"
)}
</FormDescription>
<FormMessage />
</FormItem>
);
@@ -586,6 +591,40 @@ export default function GeneralForm() {
className="space-y-4"
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">
<FormField
control={form.control}
@@ -732,40 +771,6 @@ export default function GeneralForm() {
</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>
</SettingsSectionForm>

View File

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

View File

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

View File

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