mirror of
https://github.com/BrenBroZAYT/gameyfin.git
synced 2026-06-15 08:15:37 +00:00
Implement Enum support for ConfigProperties in frontend and backend
This commit is contained in:
@@ -2,9 +2,18 @@ import ConfigEntryDto from "Frontend/generated/de/grimsi/gameyfin/config/dto/Con
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import Input from "Frontend/components/general/Input";
|
import Input from "Frontend/components/general/Input";
|
||||||
import CheckboxInput from "Frontend/components/general/CheckboxInput";
|
import CheckboxInput from "Frontend/components/general/CheckboxInput";
|
||||||
|
import SelectInput from "Frontend/components/general/SelectInput";
|
||||||
|
|
||||||
export default function ConfigFormField({configElement, ...props}: any) {
|
export default function ConfigFormField({configElement, ...props}: any) {
|
||||||
function inputElement(configElement: ConfigEntryDto) {
|
function inputElement(configElement: ConfigEntryDto) {
|
||||||
|
|
||||||
|
if (configElement.allowedValues != null && configElement.allowedValues.length > 0) {
|
||||||
|
return (
|
||||||
|
<SelectInput label={configElement.description} name={configElement.key}
|
||||||
|
values={configElement.allowedValues} {...props}/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
switch (configElement.type) {
|
switch (configElement.type) {
|
||||||
case "Boolean":
|
case "Boolean":
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -74,6 +74,38 @@ function SsoMangementLayout({getConfig, formik}: any) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const validationSchema = Yup.object({});
|
const validationSchema = Yup.object({
|
||||||
|
sso: Yup.object({
|
||||||
|
oidc: Yup.object({
|
||||||
|
enabled: Yup.boolean(),
|
||||||
|
"auto-register-new-users": Yup.boolean().required(),
|
||||||
|
"match-existing-users-by": Yup.string().required(),
|
||||||
|
"client-id": Yup.string().when("enabled", ([enabled], schema) =>
|
||||||
|
enabled ? schema.required("Client ID is required") : schema
|
||||||
|
),
|
||||||
|
"client-secret": Yup.string().when("enabled", ([enabled], schema) =>
|
||||||
|
enabled ? schema.required("Client Secret is required") : schema
|
||||||
|
),
|
||||||
|
"issuer-url": Yup.string().when("enabled", ([enabled], schema) =>
|
||||||
|
enabled ? schema.required("Issuer URL is required") : schema
|
||||||
|
),
|
||||||
|
"authorize-url": Yup.string().when("enabled", ([enabled], schema) =>
|
||||||
|
enabled ? schema.required("Authorize URL is required") : schema
|
||||||
|
),
|
||||||
|
"token-url": Yup.string().when("enabled", ([enabled], schema) =>
|
||||||
|
enabled ? schema.required("Token URL is required") : schema
|
||||||
|
),
|
||||||
|
"userinfo-url": Yup.string().when("enabled", ([enabled], schema) =>
|
||||||
|
enabled ? schema.required("Userinfo URL is required") : schema
|
||||||
|
),
|
||||||
|
"logout-url": Yup.string().when("enabled", ([enabled], schema) =>
|
||||||
|
enabled ? schema.required("Logout URL is required") : schema
|
||||||
|
),
|
||||||
|
"jwks-url": Yup.string().when("enabled", ([enabled], schema) =>
|
||||||
|
enabled ? schema.required("JWKS URL is required") : schema
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
export const SsoManagement = withConfigPage(SsoMangementLayout, "Single Sign-On", "sso", validationSchema);
|
export const SsoManagement = withConfigPage(SsoMangementLayout, "Single Sign-On", "sso", validationSchema);
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import {useField} from "formik";
|
||||||
|
import {Select, SelectItem} from "@nextui-org/react";
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
const SelectInput = ({label, values, ...props}) => {
|
||||||
|
// @ts-ignore
|
||||||
|
const [field] = useField(props);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex flex-row flex-1 items-center gap-2 my-2">
|
||||||
|
<Select
|
||||||
|
{...field}
|
||||||
|
{...props}
|
||||||
|
id={field.name}
|
||||||
|
label={label}
|
||||||
|
defaultSelectedKeys={[field.value]}
|
||||||
|
>
|
||||||
|
{values.map((value: string) => (
|
||||||
|
<SelectItem key={value} value={value}>
|
||||||
|
{value.toLowerCase()}
|
||||||
|
</SelectItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SelectInput;
|
||||||
@@ -7,7 +7,8 @@ sealed class ConfigProperties<T : Serializable>(
|
|||||||
val type: KClass<T>,
|
val type: KClass<T>,
|
||||||
val key: String,
|
val key: String,
|
||||||
val description: String,
|
val description: String,
|
||||||
val default: T? = null
|
val default: T? = null,
|
||||||
|
val allowedValues: List<T>? = null
|
||||||
) {
|
) {
|
||||||
|
|
||||||
/** Libraries */
|
/** Libraries */
|
||||||
@@ -114,7 +115,8 @@ sealed class ConfigProperties<T : Serializable>(
|
|||||||
MatchUsersBy::class,
|
MatchUsersBy::class,
|
||||||
"sso.oidc.match-existing-users-by",
|
"sso.oidc.match-existing-users-by",
|
||||||
"Match existing users by",
|
"Match existing users by",
|
||||||
MatchUsersBy.USERNAME
|
MatchUsersBy.USERNAME,
|
||||||
|
MatchUsersBy.entries
|
||||||
)
|
)
|
||||||
|
|
||||||
data object SsoAutoRegisterNewUsers : ConfigProperties<Boolean>(
|
data object SsoAutoRegisterNewUsers : ConfigProperties<Boolean>(
|
||||||
|
|||||||
@@ -40,7 +40,8 @@ class ConfigService(
|
|||||||
value = appConfig?.value ?: configProperty.default?.toString(),
|
value = appConfig?.value ?: configProperty.default?.toString(),
|
||||||
defaultValue = configProperty.default?.toString(),
|
defaultValue = configProperty.default?.toString(),
|
||||||
type = configProperty.type.simpleName ?: "Unknown",
|
type = configProperty.type.simpleName ?: "Unknown",
|
||||||
description = configProperty.description
|
description = configProperty.description,
|
||||||
|
allowedValues = configProperty.allowedValues?.map { it.toString() }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -172,9 +173,14 @@ class ConfigService(
|
|||||||
Boolean::class -> value.toBoolean() as T
|
Boolean::class -> value.toBoolean() as T
|
||||||
Int::class -> value.toFloat().toInt() as T
|
Int::class -> value.toFloat().toInt() as T
|
||||||
Float::class -> value.toFloat() as T
|
Float::class -> value.toFloat() as T
|
||||||
Enum::class -> value as T
|
|
||||||
else -> {
|
else -> {
|
||||||
throw RuntimeException("Unknown config type ${configProperty.type}: '$value' for key ${configProperty.key}")
|
if (configProperty.type.java.isEnum) {
|
||||||
|
val enumConstants = configProperty.type.java.enumConstants
|
||||||
|
enumConstants.firstOrNull { it.toString() == value }
|
||||||
|
?: throw IllegalArgumentException("Unknown enum value '$value' for key ${configProperty.key}")
|
||||||
|
} else {
|
||||||
|
throw IllegalArgumentException("Unknown config type ${configProperty.type}: '$value' for key ${configProperty.key}")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,5 +9,6 @@ data class ConfigEntryDto(
|
|||||||
val value: String?,
|
val value: String?,
|
||||||
val defaultValue: String?,
|
val defaultValue: String?,
|
||||||
@field:Nonnull val type: String,
|
@field:Nonnull val type: String,
|
||||||
@field:Nonnull val description: String
|
@field:Nonnull val description: String,
|
||||||
|
val allowedValues: List<String>?
|
||||||
)
|
)
|
||||||
Reference in New Issue
Block a user