🚧 org settings form

This commit is contained in:
Fred KISSIE
2025-12-15 23:18:28 +01:00
parent 5a0a8893e8
commit 9125a7bccb
2 changed files with 261 additions and 243 deletions

View File

@@ -1853,6 +1853,8 @@
"enableTwoFactorAuthentication": "Enable two-factor authentication", "enableTwoFactorAuthentication": "Enable two-factor authentication",
"completeSecuritySteps": "Complete Security Steps", "completeSecuritySteps": "Complete Security Steps",
"securitySettings": "Security Settings", "securitySettings": "Security Settings",
"dangerSection": "Danger section",
"dangerSectionDescription": "Delete organization alongside all its sites, clients, resources, etc...",
"securitySettingsDescription": "Configure security policies for the organization", "securitySettingsDescription": "Configure security policies for the organization",
"requireTwoFactorForAllUsers": "Require Two-Factor Authentication for All Users", "requireTwoFactorForAllUsers": "Require Two-Factor Authentication for All Users",
"requireTwoFactorDescription": "When enabled, all internal users in this organization must have two-factor authentication enabled to access the organization.", "requireTwoFactorDescription": "When enabled, all internal users in this organization must have two-factor authentication enabled to access the organization.",
@@ -2063,7 +2065,7 @@
"request": "Request", "request": "Request",
"requests": "Requests", "requests": "Requests",
"logs": "Logs", "logs": "Logs",
"logsSettingsDescription": "Monitor logs collected from this orginization", "logsSettingsDescription": "Monitor logs collected from this organization",
"searchLogs": "Search logs...", "searchLogs": "Search logs...",
"action": "Action", "action": "Action",
"actor": "Actor", "actor": "Actor",

View File

@@ -368,9 +368,9 @@ export default function GeneralPage() {
/> />
</SettingsSectionForm> </SettingsSectionForm>
</SettingsSectionBody> </SettingsSectionBody>
</SettingsSection>
<SettingsSection> <hr className="my-12 max-w-xl" />
<SettingsSectionHeader> <SettingsSectionHeader>
<SettingsSectionTitle> <SettingsSectionTitle>
{t("logRetention")} {t("logRetention")}
@@ -587,266 +587,258 @@ export default function GeneralPage() {
)} )}
</SettingsSectionForm> </SettingsSectionForm>
</SettingsSectionBody> </SettingsSectionBody>
</SettingsSection>
{build !== "oss" && ( {build !== "oss" && (
<SettingsSection> <>
<SettingsSectionHeader> <hr className="my-12 max-w-xl" />
<SettingsSectionTitle> <SettingsSectionHeader>
{t("securitySettings")} <SettingsSectionTitle>
</SettingsSectionTitle> {t("securitySettings")}
<SettingsSectionDescription> </SettingsSectionTitle>
{t("securitySettingsDescription")} <SettingsSectionDescription>
</SettingsSectionDescription> {t("securitySettingsDescription")}
</SettingsSectionHeader> </SettingsSectionDescription>
<SettingsSectionBody> </SettingsSectionHeader>
<SettingsSectionForm> <SettingsSectionBody>
<SecurityFeaturesAlert /> <SettingsSectionForm className="mb-4">
<FormField <SecurityFeaturesAlert />
control={form.control} <FormField
name="requireTwoFactor" control={form.control}
render={({ field }) => { name="requireTwoFactor"
const isDisabled = render={({ field }) => {
isSecurityFeatureDisabled(); const isDisabled =
isSecurityFeatureDisabled();
return ( return (
<FormItem className="col-span-2"> <FormItem className="col-span-2">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<FormControl>
<SwitchInput
id="require-two-factor"
defaultChecked={
field.value ||
false
}
label={t(
"requireTwoFactorForAllUsers"
)}
disabled={
isDisabled
}
onCheckedChange={(
val
) => {
if (
!isDisabled
) {
form.setValue(
"requireTwoFactor",
val
);
}
}}
/>
</FormControl>
</div>
<FormMessage />
<FormDescription>
{t(
"requireTwoFactorDescription"
)}
</FormDescription>
</FormItem>
);
}}
/>
<FormField
control={form.control}
name="maxSessionLengthHours"
render={({ field }) => {
const isDisabled =
isSecurityFeatureDisabled();
return (
<FormItem className="col-span-2">
<FormLabel>
{t(
"maxSessionLength"
)}
</FormLabel>
<FormControl> <FormControl>
<SwitchInput <Select
id="require-two-factor" value={
defaultChecked={ field.value?.toString() ||
field.value || "null"
false
} }
label={t( onValueChange={(
"requireTwoFactorForAllUsers" value
)}
disabled={
isDisabled
}
onCheckedChange={(
val
) => { ) => {
if ( if (
!isDisabled !isDisabled
) { ) {
const numValue =
value ===
"null"
? null
: parseInt(
value,
10
);
form.setValue( form.setValue(
"requireTwoFactor", "maxSessionLengthHours",
val numValue
); );
} }
}} }}
/> disabled={
isDisabled
}
>
<SelectTrigger>
<SelectValue
placeholder={t(
"selectSessionLength"
)}
/>
</SelectTrigger>
<SelectContent>
{SESSION_LENGTH_OPTIONS.map(
(
option
) => (
<SelectItem
key={
option.value ===
null
? "null"
: option.value.toString()
}
value={
option.value ===
null
? "null"
: option.value.toString()
}
>
{t(
option.labelKey
)}
</SelectItem>
)
)}
</SelectContent>
</Select>
</FormControl> </FormControl>
</div>
<FormMessage />
<FormDescription>
{t(
"requireTwoFactorDescription"
)}
</FormDescription>
</FormItem>
);
}}
/>
<FormField
control={form.control}
name="maxSessionLengthHours"
render={({ field }) => {
const isDisabled =
isSecurityFeatureDisabled();
return (
<FormItem className="col-span-2">
<FormLabel>
{t("maxSessionLength")}
</FormLabel>
<FormControl>
<Select
value={
field.value?.toString() ||
"null"
}
onValueChange={(
value
) => {
if (
!isDisabled
) {
const numValue =
value ===
"null"
? null
: parseInt(
value,
10
);
form.setValue(
"maxSessionLengthHours",
numValue
);
}
}}
disabled={
isDisabled
}
>
<SelectTrigger>
<SelectValue
placeholder={t(
"selectSessionLength"
)}
/>
</SelectTrigger>
<SelectContent>
{SESSION_LENGTH_OPTIONS.map(
(
option
) => (
<SelectItem
key={
option.value ===
null
? "null"
: option.value.toString()
}
value={
option.value ===
null
? "null"
: option.value.toString()
}
>
{t(
option.labelKey
)}
</SelectItem>
)
)}
</SelectContent>
</Select>
</FormControl>
<FormMessage />
<FormDescription>
{t(
"maxSessionLengthDescription"
)}
</FormDescription>
</FormItem>
);
}}
/>
<FormField
control={form.control}
name="passwordExpiryDays"
render={({ field }) => {
const isDisabled =
isSecurityFeatureDisabled();
return (
<FormItem className="col-span-2">
<FormLabel>
{t(
"passwordExpiryDays"
)}
</FormLabel>
<FormControl>
<Select
value={
field.value?.toString() ||
"null"
}
onValueChange={(
value
) => {
if (
!isDisabled
) {
const numValue =
value ===
"null"
? null
: parseInt(
value,
10
);
form.setValue(
"passwordExpiryDays",
numValue
);
}
}}
disabled={
isDisabled
}
>
<SelectTrigger>
<SelectValue
placeholder={t(
"selectPasswordExpiry"
)}
/>
</SelectTrigger>
<SelectContent>
{PASSWORD_EXPIRY_OPTIONS.map(
(
option
) => (
<SelectItem
key={
option.value ===
null
? "null"
: option.value.toString()
}
value={
option.value ===
null
? "null"
: option.value.toString()
}
>
{t(
option.labelKey
)}
</SelectItem>
)
)}
</SelectContent>
</Select>
</FormControl>
<FormDescription>
<FormMessage /> <FormMessage />
{t( <FormDescription>
"editPasswordExpiryDescription" {t(
)} "maxSessionLengthDescription"
</FormDescription> )}
</FormItem> </FormDescription>
); </FormItem>
}} );
/> }}
</SettingsSectionForm> />
</SettingsSectionBody> <FormField
</SettingsSection> control={form.control}
)} name="passwordExpiryDays"
render={({ field }) => {
const isDisabled =
isSecurityFeatureDisabled();
return (
<FormItem className="col-span-2">
<FormLabel>
{t(
"passwordExpiryDays"
)}
</FormLabel>
<FormControl>
<Select
value={
field.value?.toString() ||
"null"
}
onValueChange={(
value
) => {
if (
!isDisabled
) {
const numValue =
value ===
"null"
? null
: parseInt(
value,
10
);
form.setValue(
"passwordExpiryDays",
numValue
);
}
}}
disabled={
isDisabled
}
>
<SelectTrigger>
<SelectValue
placeholder={t(
"selectPasswordExpiry"
)}
/>
</SelectTrigger>
<SelectContent>
{PASSWORD_EXPIRY_OPTIONS.map(
(
option
) => (
<SelectItem
key={
option.value ===
null
? "null"
: option.value.toString()
}
value={
option.value ===
null
? "null"
: option.value.toString()
}
>
{t(
option.labelKey
)}
</SelectItem>
)
)}
</SelectContent>
</Select>
</FormControl>
<FormDescription>
<FormMessage />
{t(
"editPasswordExpiryDescription"
)}
</FormDescription>
</FormItem>
);
}}
/>
</SettingsSectionForm>
</SettingsSectionBody>
</>
)}
</SettingsSection>
</form> </form>
</Form> </Form>
{build === "saas" && <AuthPageSettings ref={authPageSettingsRef} />} {build === "saas" && <AuthPageSettings ref={authPageSettingsRef} />}
<div className="flex justify-end gap-2"> <div className="flex justify-end gap-2">
{build !== "saas" && (
<Button
variant="destructive"
onClick={() => setIsDeleteModalOpen(true)}
className="flex items-center gap-2"
loading={loadingDelete}
disabled={loadingDelete}
>
{t("orgDelete")}
</Button>
)}
<Button <Button
type="submit" type="submit"
form="org-settings-form" form="org-settings-form"
@@ -856,6 +848,30 @@ export default function GeneralPage() {
{t("saveSettings")} {t("saveSettings")}
</Button> </Button>
</div> </div>
{build !== "saas" && (
<SettingsSection>
<SettingsSectionHeader>
<SettingsSectionTitle>
{t("dangerSection")}
</SettingsSectionTitle>
<SettingsSectionDescription>
{t("dangerSectionDescription")}
</SettingsSectionDescription>
</SettingsSectionHeader>
<div className="flex justify-start gap-2">
<Button
variant="destructive"
onClick={() => setIsDeleteModalOpen(true)}
className="flex items-center gap-2"
loading={loadingDelete}
disabled={loadingDelete}
>
{t("orgDelete")}
</Button>
</div>
</SettingsSection>
)}
</SettingsContainer> </SettingsContainer>
); );
} }