Small UI tweaks

This commit is contained in:
grimsi
2025-05-19 13:49:15 +02:00
parent d9fef0f30c
commit eab23d48e1
6 changed files with 39 additions and 34 deletions
@@ -16,8 +16,15 @@ interface PluginDetailsModalProps {
onOpenChange: () => void;
}
enum ValidationState {
UNCHECKED,
VALID,
INVALID,
IN_PROGRESS
}
export default function PluginDetailsModal({plugin, isOpen, onOpenChange}: PluginDetailsModalProps) {
const [configValidated, setConfigValidated] = useState<boolean>(false);
const [configValidated, setConfigValidated] = useState<ValidationState>(ValidationState.UNCHECKED);
async function saveConfig(values: Record<string, string>) {
await PluginEndpoint.updateConfig(plugin.id, values);
@@ -94,21 +101,36 @@ export default function PluginDetailsModal({plugin, isOpen, onOpenChange}: Plugi
<div className="flex flex-row items-center mt-4 gap-2">
<h4 className="text-l font-bold">Configuration</h4>
<div className="flex-1"/>
{(plugin.configMetadata && plugin.configMetadata.length > 0) && <>
{configValidated &&
<p className="text-small text-success">Validation successful</p>}
<div className="flex-1"/>
{(() => {
switch (configValidated) {
case ValidationState.VALID:
return <p className="text-small text-success">
Configuration valid
</p>;
case ValidationState.INVALID:
return <p className="text-small text-danger">
Configuration invalid
</p>;
default:
return null;
}
})()}
<Tooltip content="Re-validate configuration" placement="bottom"
color="foreground">
<Button isIconOnly variant="light" size="sm"
isLoading={configValidated === ValidationState.IN_PROGRESS}
onPress={async () => {
setConfigValidated(false);
setConfigValidated(ValidationState.IN_PROGRESS);
let result = await PluginEndpoint.validateNewConfig(plugin.id, formik.values)
if (result.errors) formik.setErrors(result.errors);
else {
setConfigValidated(true);
setTimeout(() => setConfigValidated(false), 5000);
if (result.errors) {
formik.setErrors(result.errors);
setConfigValidated(ValidationState.INVALID);
} else {
setConfigValidated(ValidationState.VALID);
}
setTimeout(() => setConfigValidated(ValidationState.UNCHECKED), 5000);
}}>
<ArrowClockwise/>
</Button>
@@ -131,7 +153,7 @@ export default function PluginDetailsModal({plugin, isOpen, onOpenChange}: Plugi
<Button
color="primary"
isLoading={formik.isSubmitting}
disabled={formik.isSubmitting}
isDisabled={formik.isSubmitting || !formik.dirty}
type="submit"
>
{formik.isSubmitting ? "" : "Save"}
@@ -3,7 +3,6 @@ package de.grimsi.gameyfin.core.plugins
import com.vaadin.hilla.Endpoint
import de.grimsi.gameyfin.core.Role
import de.grimsi.gameyfin.core.plugins.dto.PluginUpdateDto
import de.grimsi.gameyfin.core.plugins.management.PluginService
import de.grimsi.gameyfin.pluginapi.core.PluginConfigValidationResult
import de.grimsi.gameyfin.users.util.isAdmin
import jakarta.annotation.security.PermitAll
@@ -1,11 +1,14 @@
package de.grimsi.gameyfin.core.plugins.management
package de.grimsi.gameyfin.core.plugins
import de.grimsi.gameyfin.core.plugins.config.PluginConfigEntry
import de.grimsi.gameyfin.core.plugins.config.PluginConfigEntryKey
import de.grimsi.gameyfin.core.plugins.config.PluginConfigRepository
import de.grimsi.gameyfin.core.plugins.config.PluginConfigService
import de.grimsi.gameyfin.core.plugins.dto.PluginDto
import de.grimsi.gameyfin.core.plugins.dto.PluginUpdateDto
import de.grimsi.gameyfin.core.plugins.management.GameyfinPluginDescriptor
import de.grimsi.gameyfin.core.plugins.management.GameyfinPluginManager
import de.grimsi.gameyfin.core.plugins.management.PluginManagementEntry
import de.grimsi.gameyfin.core.plugins.management.PluginManagementRepository
import de.grimsi.gameyfin.pluginapi.core.Configurable
import de.grimsi.gameyfin.pluginapi.core.GameyfinPlugin
import de.grimsi.gameyfin.pluginapi.core.PluginConfigElement
@@ -21,7 +24,6 @@ import reactor.core.publisher.Sinks
@Service
class PluginService(
private val pluginManager: GameyfinPluginManager,
private val pluginConfigService: PluginConfigService,
private val pluginManagementRepository: PluginManagementRepository,
private val pluginConfigRepository: PluginConfigRepository
) {
@@ -1,18 +0,0 @@
package de.grimsi.gameyfin.core.plugins.config
import de.grimsi.gameyfin.core.plugins.management.GameyfinPluginManager
import io.github.oshai.kotlinlogging.KotlinLogging
import org.springframework.stereotype.Service
@Service
class PluginConfigService(
private val pluginConfigRepository: PluginConfigRepository,
private val pluginManager: GameyfinPluginManager
) {
companion object {
private val log = KotlinLogging.logger {}
}
}
@@ -2,8 +2,8 @@ package de.grimsi.gameyfin.games
import de.grimsi.gameyfin.core.alphaNumeric
import de.grimsi.gameyfin.core.filterValuesNotNull
import de.grimsi.gameyfin.core.plugins.PluginService
import de.grimsi.gameyfin.core.plugins.management.PluginManagementEntry
import de.grimsi.gameyfin.core.plugins.management.PluginService
import de.grimsi.gameyfin.core.replaceRomanNumerals
import de.grimsi.gameyfin.games.dto.GameDto
import de.grimsi.gameyfin.games.dto.GameMetadataDto
@@ -3,7 +3,7 @@ package de.grimsi.gameyfin.media
import de.grimsi.gameyfin.core.Role
import de.grimsi.gameyfin.core.Utils
import de.grimsi.gameyfin.core.annotations.DynamicPublicAccess
import de.grimsi.gameyfin.core.plugins.management.PluginService
import de.grimsi.gameyfin.core.plugins.PluginService
import de.grimsi.gameyfin.games.entities.Image
import de.grimsi.gameyfin.games.entities.ImageType
import de.grimsi.gameyfin.users.UserService