From 3bb47e251e91e08f6ccd5d9de48e640092a7533f Mon Sep 17 00:00:00 2001 From: FyWolf Date: Tue, 26 Nov 2024 00:40:21 +0100 Subject: [PATCH] Added preset renaming --- .../modpreset/ModPresetsController.java | 19 +++++++ .../dtos/RenamePresetRequestDto.java | 13 +++++ .../src/components/mods/PresetsManagement.tsx | 41 +++++++++++++- .../components/mods/RenamePresetDialog.tsx | 53 +++++++++++++++++++ frontend/src/dtos/ModPresetDto.ts | 4 ++ frontend/src/services/modPresetsService.ts | 6 ++- 6 files changed, 133 insertions(+), 3 deletions(-) create mode 100644 backend/src/main/java/cz/forgottenempire/servermanager/modpreset/dtos/RenamePresetRequestDto.java create mode 100644 frontend/src/components/mods/RenamePresetDialog.tsx diff --git a/backend/src/main/java/cz/forgottenempire/servermanager/modpreset/ModPresetsController.java b/backend/src/main/java/cz/forgottenempire/servermanager/modpreset/ModPresetsController.java index 7f0074bc..cdd0acbd 100644 --- a/backend/src/main/java/cz/forgottenempire/servermanager/modpreset/ModPresetsController.java +++ b/backend/src/main/java/cz/forgottenempire/servermanager/modpreset/ModPresetsController.java @@ -7,6 +7,7 @@ import cz.forgottenempire.servermanager.modpreset.dtos.PresetListResponseDto; import cz.forgottenempire.servermanager.modpreset.dtos.PresetResponseDto; import cz.forgottenempire.servermanager.modpreset.dtos.UpdatePresetRequestDto; +import cz.forgottenempire.servermanager.modpreset.dtos.RenamePresetRequestDto; import cz.forgottenempire.servermanager.workshop.WorkshopMod; import cz.forgottenempire.servermanager.workshop.WorkshopModsService; import java.util.Collection; @@ -89,6 +90,24 @@ public ResponseEntity updatePreset( return ResponseEntity.ok(modPresetMapper.mapToModPresetDto(modPreset)); } + @PutMapping("/rename/{id}") + public ResponseEntity renamePreset( + @PathVariable Long id, + @Valid @RequestBody RenamePresetRequestDto requestDto + ) { + ModPreset modPreset = modPresetsService.getModPreset(id) + .orElseThrow(() -> new NotFoundException("Mod preset " + id + " not found")); + + if (!modPreset.getName().equals(requestDto.getName())) { + validatePresetName(requestDto.getName()); + } + + modPreset.setName(requestDto.getName()); + modPreset = modPresetsService.updatePreset(modPreset); + return ResponseEntity.ok(modPresetMapper.mapToModPresetDto(modPreset)); + } + + @DeleteMapping("/{id}") public ResponseEntity deletePreset(@PathVariable Long id) { modPresetsService.deletePreset(id); diff --git a/backend/src/main/java/cz/forgottenempire/servermanager/modpreset/dtos/RenamePresetRequestDto.java b/backend/src/main/java/cz/forgottenempire/servermanager/modpreset/dtos/RenamePresetRequestDto.java new file mode 100644 index 00000000..6085ae0f --- /dev/null +++ b/backend/src/main/java/cz/forgottenempire/servermanager/modpreset/dtos/RenamePresetRequestDto.java @@ -0,0 +1,13 @@ +package cz.forgottenempire.servermanager.modpreset.dtos; + +import jakarta.validation.constraints.NotEmpty; +import lombok.Data; + +import java.util.List; + +@Data +public class RenamePresetRequestDto { + + @NotEmpty + private String name; +} diff --git a/frontend/src/components/mods/PresetsManagement.tsx b/frontend/src/components/mods/PresetsManagement.tsx index 5888916b..230cffff 100644 --- a/frontend/src/components/mods/PresetsManagement.tsx +++ b/frontend/src/components/mods/PresetsManagement.tsx @@ -17,7 +17,6 @@ import {Backdrop, Box, CircularProgress, Divider, Modal, Stack, Toolbar} from "@ import Typography from "@mui/material/Typography"; import IconButton from '@mui/material/IconButton'; import DeleteIcon from '@mui/icons-material/Delete'; -import EditIcon from '@mui/icons-material/Edit'; import SERVER_NAMES from "../../util/serverNames"; import {toast} from "material-react-toastify"; import ListBuilder from "../../UI/ListBuilder/ListBuilder"; @@ -29,6 +28,10 @@ import DownloadIcon from '@mui/icons-material/Download'; import {ModPresetDto, ModPresetModDto} from "../../dtos/ModPresetDto"; import {ModDto} from "../../dtos/ModDto.ts"; import {ServerType} from "../../dtos/ServerDto.ts"; +import DriveFileRenameOutlineOutlinedIcon from '@mui/icons-material/DriveFileRenameOutlineOutlined'; +import RenamePresetDialog from "./RenamePresetDialog"; +import MemoryIcon from "@mui/icons-material/Memory"; +import {renameModPreset} from "../../services/modPresetsService"; export default function PresetsManagement() { const [initialLoading, setInitialLoading] = useState(true); @@ -38,6 +41,8 @@ export default function PresetsManagement() { const [selectedMods, setSelectedMods] = useState>([]); const [availableMods, setAvailableMods] = useState>([]); const [isUploadInProgress, setIsUploadInProgress] = useState(false); + const [renamePresetDialogOpen, setRenamePresetDialogOpen] = useState(false); + const [selectedPresetId, setSelectedPresetId] = useState(null); useEffect(() => { async function fetchPresets() { @@ -177,6 +182,29 @@ export default function PresetsManagement() { } } + const handlePresedDialogOpen = (presetId: string) => { + setSelectedPresetId(presetId); + setRenamePresetDialogOpen(true); + } + + const handlePresedDialogClose = () => { + setRenamePresetDialogOpen(false); + setSelectedPresetId(null); + } + + const handleRenameNewPreset = async (presetName: string, presetId: string) => { + setRenamePresetDialogOpen(false); + setSelectedPresetId(null); + + const request = { + name: presetName, + } + + await renameModPreset(presetId, request); + toast.success(`Preset '${presetName}' successfully renamed`); + window.location.reload(); + } + return ( <> @@ -233,7 +261,13 @@ export default function PresetsManagement() { handleOpenEdit(preset)}> - + + + + + handlePresedDialogOpen(preset.id as string)}> + @@ -264,6 +298,9 @@ export default function PresetsManagement() { /> + ) } \ No newline at end of file diff --git a/frontend/src/components/mods/RenamePresetDialog.tsx b/frontend/src/components/mods/RenamePresetDialog.tsx new file mode 100644 index 00000000..35c253cc --- /dev/null +++ b/frontend/src/components/mods/RenamePresetDialog.tsx @@ -0,0 +1,53 @@ +import {ChangeEvent, useState} from "react"; +import Button from '@mui/material/Button'; +import TextField from '@mui/material/TextField'; +import Dialog from '@mui/material/Dialog'; +import DialogActions from '@mui/material/DialogActions'; +import DialogContent from '@mui/material/DialogContent'; +import DialogTitle from '@mui/material/DialogTitle'; + +type RenamePresetDialogProps = { + open: boolean, + onConfirmClicked: (name: string, id: string) => void, + onClose: () => void, + presetId: string | null +} + +const RenamePresetDialog = (props: RenamePresetDialogProps) => { + const [presetName, setPresetName] = useState(""); + + const handlePresetNameChange = (e: ChangeEvent) => { + setPresetName(e.target.value); + } + + const handleConfirmClicked = () => { + if (props.presetId) { // Ensure the ID is available + props.onConfirmClicked(presetName, props.presetId); + setPresetName(""); // Reset the input field + } + }; + + return ( + + Rename preset + + + + + + + + + ); +}; + +export default RenamePresetDialog; \ No newline at end of file diff --git a/frontend/src/dtos/ModPresetDto.ts b/frontend/src/dtos/ModPresetDto.ts index 2b1b9d50..2ffb3d05 100644 --- a/frontend/src/dtos/ModPresetDto.ts +++ b/frontend/src/dtos/ModPresetDto.ts @@ -21,4 +21,8 @@ export interface ModPresetModDto { id: number, name: string, shortName: string +} + +export interface ModPresetRenameDto { + name: string } \ No newline at end of file diff --git a/frontend/src/services/modPresetsService.ts b/frontend/src/services/modPresetsService.ts index 3b53dba4..c0182401 100644 --- a/frontend/src/services/modPresetsService.ts +++ b/frontend/src/services/modPresetsService.ts @@ -1,6 +1,6 @@ import http from "./httpService"; import config from "../config"; -import {ModPresetRequestDto} from "../dtos/ModPresetDto.ts"; +import {ModPresetRequestDto, ModPresetRenameDto} from "../dtos/ModPresetDto.ts"; const apiEndpoint = config.apiUrl + "/mod/preset"; @@ -25,6 +25,10 @@ export function updateModPreset(id: string, preset: ModPresetRequestDto) { return http.put(apiEndpoint + "/" + id, preset); } +export function renameModPreset(id: string, preset: ModPresetRenameDto) { + return http.put(apiEndpoint + "/rename/" + id, preset); +} + export function deleteModPreset(id: string) { return http.delete(apiEndpoint + "/" + id); }