From 0dace76fc333eb6ce4b1abb2ecf589af9edb494a Mon Sep 17 00:00:00 2001 From: Thibaut Valentin Date: Sat, 27 Dec 2025 17:06:27 +0100 Subject: [PATCH] feat: cat remove --- .../java/fr/titionfire/ffsaf/utils/Utils.java | 30 ++++++++++++++++++ .../titionfire/ffsaf/ws/recv/RCategorie.java | 13 +++++++- .../titionfire/ffsaf/ws/send/SSCategorie.java | 4 +++ .../src/pages/competition/editor/CMAdmin.jsx | 31 +++++++++++++++++-- .../competition/editor/CMTMatchPanel.jsx | 21 ++++++++++++- 5 files changed, 94 insertions(+), 5 deletions(-) diff --git a/src/main/java/fr/titionfire/ffsaf/utils/Utils.java b/src/main/java/fr/titionfire/ffsaf/utils/Utils.java index c3cdd73..b541a2e 100644 --- a/src/main/java/fr/titionfire/ffsaf/utils/Utils.java +++ b/src/main/java/fr/titionfire/ffsaf/utils/Utils.java @@ -335,4 +335,34 @@ public class Utils { return (int) ((calendar.getTimeInMillis() - now.getTimeInMillis()) / (1000 * 60 * 60 * 24)); } + + public static String formatPrenom(String input) { + if (input == null || input.isEmpty()) { + return input; + } + + StringBuilder result = new StringBuilder(); + String[] mots = input.split(" "); + + for (String mot : mots) { + if (!mot.isEmpty()) { + String[] parties = mot.split("[-']"); + StringBuilder motFormate = new StringBuilder(); + + for (int i = 0; i < parties.length; i++) { + if (!parties[i].isEmpty()) { + String premiereLettre = parties[i].substring(0, 1).toUpperCase(); + String reste = parties[i].substring(1).toLowerCase(); + motFormate.append(premiereLettre).append(reste); + } + + if (i < parties.length - 1) { + motFormate.append(mot.charAt(mot.indexOf(parties[i]) + parties[i].length())); + } + } + result.append(motFormate).append(" "); + } + } + return result.toString().trim(); + } } diff --git a/src/main/java/fr/titionfire/ffsaf/ws/recv/RCategorie.java b/src/main/java/fr/titionfire/ffsaf/ws/recv/RCategorie.java index 816cbea..317ff0d 100644 --- a/src/main/java/fr/titionfire/ffsaf/ws/recv/RCategorie.java +++ b/src/main/java/fr/titionfire/ffsaf/ws/recv/RCategorie.java @@ -118,7 +118,8 @@ public class RCategorie { uni = uni.chain(__ -> treeRepository.delete("category = ?1", cat.getId())) .chain(__ -> matchRepository.delete("category = ?1 AND category_ord = -42", cat)); } - return uni; + Uni finalUni = uni; + return Panache.withTransaction(() -> finalUni); }) .call(cat -> SSCategorie.sendCategory(connection, cat)) .replaceWithVoid(); @@ -205,6 +206,16 @@ public class RCategorie { .replaceWithVoid(); } + @WSReceiver(code = "deleteCategory", permission = PermLevel.ADMIN) + public Uni deleteCategory(WebSocketConnection connection, Long id) { + return getById(id, connection) + .call(cat -> Panache.withTransaction(() -> treeRepository.delete("category = ?1", cat.getId()) + .call(__ -> matchRepository.delete("category = ?1", cat)))) + .chain(cat -> Panache.withTransaction(() -> categoryRepository.delete(cat))) + .call(__ -> SSCategorie.sendDelCategory(connection, id)) + .replaceWithVoid(); + } + @RegisterForReflection public record JustCategorie(long id, String name, int type, String liceName) { public static JustCategorie from(CategoryModel m) { diff --git a/src/main/java/fr/titionfire/ffsaf/ws/send/SSCategorie.java b/src/main/java/fr/titionfire/ffsaf/ws/send/SSCategorie.java index 23162b9..e981080 100644 --- a/src/main/java/fr/titionfire/ffsaf/ws/send/SSCategorie.java +++ b/src/main/java/fr/titionfire/ffsaf/ws/send/SSCategorie.java @@ -30,4 +30,8 @@ public class SSCategorie { public static Uni sendTreeCategory(WebSocketConnection connection, List treeEntities) { return CompetitionWS.sendNotifyToOtherEditor(connection, "sendTreeCategory", treeEntities); } + + public static Uni sendDelCategory(WebSocketConnection connection, Long id) { + return CompetitionWS.sendNotifyToOtherEditor(connection, "sendDelCategory", id); + } } diff --git a/src/main/webapp/src/pages/competition/editor/CMAdmin.jsx b/src/main/webapp/src/pages/competition/editor/CMAdmin.jsx index 0389c44..6bc3372 100644 --- a/src/main/webapp/src/pages/competition/editor/CMAdmin.jsx +++ b/src/main/webapp/src/pages/competition/editor/CMAdmin.jsx @@ -63,22 +63,31 @@ function CategoryHeader({cat, setCatId}) { const sendAddCategory = ({data}) => { setCats([...cats, data]) } + const sendDelCategory = ({data}) => { + setCatId(catId => { + if (catId === data) return null; + return catId; + }) + setCats([...cats.filter(c => c.id !== data)]) + } dispatch({type: 'addListener', payload: {callback: categoryListener, code: 'sendCategory'}}) dispatch({type: 'addListener', payload: {callback: sendAddCategory, code: 'sendAddCategory'}}) + dispatch({type: 'addListener', payload: {callback: sendDelCategory, code: 'sendDelCategory'}}) return () => { dispatch({type: 'removeListener', payload: categoryListener}) dispatch({type: 'removeListener', payload: sendAddCategory}) + dispatch({type: 'removeListener', payload: sendDelCategory}) } }, [cats]); useEffect(() => { - if (cats && cats.length > 0 && !cat) { + if (cats && cats.length > 0 && !cat || (cats && !cats.find(c => c.id === cat.id))) { setCatId(cats.sort((a, b) => a.name.localeCompare(b.name))[0].id); } else if (cats && cats.length === 0) { setModal({}); bthRef.current.click(); } - }, [cats]); + }, [cats, cat]); const handleCatChange = (e) => { const selectedCatId = e.target.value; @@ -306,7 +315,7 @@ function ModalContent({state, setCatId, setConfirm, confirmRef}) { return
-

Ajouter une catégorie

+

{state.id === undefined ? "Ajouter" : "Modifier"} une catégorie

@@ -380,6 +389,22 @@ function ModalContent({state, setCatId, setConfirm, confirmRef}) {
+ {state.id !== undefined && }
} diff --git a/src/main/webapp/src/pages/competition/editor/CMTMatchPanel.jsx b/src/main/webapp/src/pages/competition/editor/CMTMatchPanel.jsx index f8dc315..c8eae3f 100644 --- a/src/main/webapp/src/pages/competition/editor/CMTMatchPanel.jsx +++ b/src/main/webapp/src/pages/competition/editor/CMTMatchPanel.jsx @@ -27,8 +27,22 @@ export function CategorieSelect({catId, setCatId, menuActions}) { const categoryListener = ({data}) => { setCats([...cats.filter(c => c.id !== data.id), data]) } + const sendAddCategory = ({data}) => { + setCats([...cats, data]) + } + const sendDelCategory = ({data}) => { + if (catId === data) + setCatId(-1); + setCats([...cats.filter(c => c.id !== data)]) + } dispatch({type: 'addListener', payload: {callback: categoryListener, code: 'sendCategory'}}) - return () => dispatch({type: 'removeListener', payload: categoryListener}) + dispatch({type: 'addListener', payload: {callback: sendAddCategory, code: 'sendAddCategory'}}) + dispatch({type: 'addListener', payload: {callback: sendDelCategory, code: 'sendDelCategory'}}) + return () => { + dispatch({type: 'removeListener', payload: categoryListener}) + dispatch({type: 'removeListener', payload: sendAddCategory}) + dispatch({type: 'removeListener', payload: sendDelCategory}) + } }, [cats]); const cat = cats?.find(c => c.id === catId); @@ -131,10 +145,15 @@ function ListMatch({cat, matches, trees, menuActions}) { const [type, setType] = useState(1); useEffect(() => { + if (!cat) + return; if ((cat.type & type) === 0) setType(cat.type); }, [cat]); + if (!cat) + return <>; + return
{cat && cat.type === 3 && <>