dev #107
@ -33,10 +33,11 @@ public class SRegister {
|
|||||||
public Uni<Void> sendRegister(String uuid, RegisterModel registerModel) {
|
public Uni<Void> sendRegister(String uuid, RegisterModel registerModel) {
|
||||||
return Mutiny.fetch(registerModel.getCategoriesInscrites()).chain(o ->
|
return Mutiny.fetch(registerModel.getCategoriesInscrites()).chain(o ->
|
||||||
send(uuid, "sendRegister", CombEntity.fromModel(registerModel).addCategoriesInscrites(o))
|
send(uuid, "sendRegister", CombEntity.fromModel(registerModel).addCategoriesInscrites(o))
|
||||||
.call(__ -> cardService.addTeamCartToNewComb(registerModel.getMembre().getId(),
|
.call(__ -> registerModel.getClub2() == null ? Uni.createFrom().voidItem() :
|
||||||
registerModel.getClub2().getClubId(), registerModel.getClub2().getName(),
|
cardService.addTeamCartToNewComb(registerModel.getMembre().getId(),
|
||||||
registerModel.getCompetition())
|
registerModel.getClub2().getClubId(), registerModel.getClub2().getName(),
|
||||||
.chain(cardModels -> send(uuid, "sendCards", cardModels))));
|
registerModel.getCompetition())
|
||||||
|
.chain(cardModels -> send(uuid, "sendCards", cardModels))));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Uni<Void> sendRegister(String uuid, CompetitionGuestModel model) {
|
public Uni<Void> sendRegister(String uuid, CompetitionGuestModel model) {
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
"actuel": "Current",
|
"actuel": "Current",
|
||||||
"administration": "Administration",
|
"administration": "Administration",
|
||||||
"adresseDuServeur": "Server address",
|
"adresseDuServeur": "Server address",
|
||||||
|
"ajoutAutomatique": "Automatic addition",
|
||||||
"ajouter": "Add",
|
"ajouter": "Add",
|
||||||
"ajouterDesCombattants": "Add fighters",
|
"ajouterDesCombattants": "Add fighters",
|
||||||
"ajouterUn": "Add one",
|
"ajouterUn": "Add one",
|
||||||
@ -37,6 +38,7 @@
|
|||||||
"chronomètre": "Stopwatch",
|
"chronomètre": "Stopwatch",
|
||||||
"classement": "Ranking",
|
"classement": "Ranking",
|
||||||
"club": "Club",
|
"club": "Club",
|
||||||
|
"combattantsCorrespondentAuxSélectionnés": "fighter(s) match the selections above",
|
||||||
"compétition": "Competition",
|
"compétition": "Competition",
|
||||||
"compétitionManager": "Competition manager",
|
"compétitionManager": "Competition manager",
|
||||||
"config.obs.dossierDesResources": "Resources folder",
|
"config.obs.dossierDesResources": "Resources folder",
|
||||||
@ -107,6 +109,7 @@
|
|||||||
"poule": "Pool",
|
"poule": "Pool",
|
||||||
"poulePour": "Pool for: ",
|
"poulePour": "Pool for: ",
|
||||||
"préparation...": "Preparing...",
|
"préparation...": "Preparing...",
|
||||||
|
"remplacer": "Replace",
|
||||||
"rouge": "Red",
|
"rouge": "Red",
|
||||||
"réinitialiser": "Reset",
|
"réinitialiser": "Reset",
|
||||||
"résultat": "Result",
|
"résultat": "Result",
|
||||||
@ -179,6 +182,7 @@
|
|||||||
"téléchargementEnCours": "Downloading...",
|
"téléchargementEnCours": "Downloading...",
|
||||||
"téléchargementTerminé!": "Download completed!",
|
"téléchargementTerminé!": "Download completed!",
|
||||||
"uneCatégorie": "a category",
|
"uneCatégorie": "a category",
|
||||||
|
"uneCatégorieNePeutContenirPlusDe10Combattants": "A category cannot contain more than 10 fighters, please create weight categories.",
|
||||||
"valider": "Validate",
|
"valider": "Validate",
|
||||||
"zone": "Zone",
|
"zone": "Zone",
|
||||||
"zoneDeCombat": "Combat zone"
|
"zoneDeCombat": "Combat zone"
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
"actuel": "Actuel",
|
"actuel": "Actuel",
|
||||||
"administration": "Administration",
|
"administration": "Administration",
|
||||||
"adresseDuServeur": "Adresse du serveur",
|
"adresseDuServeur": "Adresse du serveur",
|
||||||
|
"ajoutAutomatique": "Ajout automatique",
|
||||||
"ajouter": "Ajouter",
|
"ajouter": "Ajouter",
|
||||||
"ajouterDesCombattants": "Ajouter des combattants",
|
"ajouterDesCombattants": "Ajouter des combattants",
|
||||||
"ajouterUn": "Ajouter un ",
|
"ajouterUn": "Ajouter un ",
|
||||||
@ -37,6 +38,7 @@
|
|||||||
"chronomètre": "Chronomètre",
|
"chronomètre": "Chronomètre",
|
||||||
"classement": "Classement",
|
"classement": "Classement",
|
||||||
"club": "Club",
|
"club": "Club",
|
||||||
|
"combattantsCorrespondentAuxSélectionnés": "combattant(s) correspondent aux sélectionnés ci-dessus.",
|
||||||
"compétition": "Compétition",
|
"compétition": "Compétition",
|
||||||
"compétitionManager": "Compétition manager",
|
"compétitionManager": "Compétition manager",
|
||||||
"config.obs.dossierDesResources": "Dossier des resources",
|
"config.obs.dossierDesResources": "Dossier des resources",
|
||||||
@ -107,6 +109,7 @@
|
|||||||
"poule": "Poule",
|
"poule": "Poule",
|
||||||
"poulePour": "Poule pour: ",
|
"poulePour": "Poule pour: ",
|
||||||
"préparation...": "Préparation...",
|
"préparation...": "Préparation...",
|
||||||
|
"remplacer": "Remplacer",
|
||||||
"rouge": "Rouge",
|
"rouge": "Rouge",
|
||||||
"réinitialiser": "Réinitialiser",
|
"réinitialiser": "Réinitialiser",
|
||||||
"résultat": "Résultat",
|
"résultat": "Résultat",
|
||||||
@ -179,6 +182,7 @@
|
|||||||
"téléchargementEnCours": "Téléchargement en cours...",
|
"téléchargementEnCours": "Téléchargement en cours...",
|
||||||
"téléchargementTerminé!": "Téléchargement terminé !",
|
"téléchargementTerminé!": "Téléchargement terminé !",
|
||||||
"uneCatégorie": "une catégorie",
|
"uneCatégorie": "une catégorie",
|
||||||
|
"uneCatégorieNePeutContenirPlusDe10Combattants": "Une catégorie ne peut contenir plus de 10 combattants, veuillez créer des catégories de poids.",
|
||||||
"valider": "Valider",
|
"valider": "Valider",
|
||||||
"zone": "Zone",
|
"zone": "Zone",
|
||||||
"zoneDeCombat": "Zone de combat"
|
"zoneDeCombat": "Zone de combat"
|
||||||
|
|||||||
232
src/main/webapp/src/components/cm/AutoCatModalContent.jsx
Normal file
232
src/main/webapp/src/components/cm/AutoCatModalContent.jsx
Normal file
@ -0,0 +1,232 @@
|
|||||||
|
import React, {useEffect, useState} from "react";
|
||||||
|
import {useTranslation} from "react-i18next";
|
||||||
|
import {useCountries} from "../../hooks/useCountries.jsx";
|
||||||
|
import {ListPresetSelect} from "./ListPresetSelect.jsx";
|
||||||
|
import {CatList, getCatName} from "../../utils/Tools.js";
|
||||||
|
|
||||||
|
export function AutoCatModalContent({data, groups, setGroups, defaultPreset = -1}) {
|
||||||
|
const country = useCountries('fr')
|
||||||
|
const {t} = useTranslation("cm");
|
||||||
|
|
||||||
|
const [country_, setCountry_] = useState("")
|
||||||
|
const [gender, setGender] = useState({H: true, F: true, NA: true})
|
||||||
|
const [cat, setCat] = useState([])
|
||||||
|
const [weightMin, setWeightMin] = useState(0)
|
||||||
|
const [weightMax, setWeightMax] = useState(0)
|
||||||
|
const [team, setTeam] = useState(false)
|
||||||
|
const [preset, setPreset] = useState(-1)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setPreset(defaultPreset)
|
||||||
|
}, [defaultPreset])
|
||||||
|
|
||||||
|
const setCat_ = (e, index) => {
|
||||||
|
if (e.target.checked) {
|
||||||
|
if (!cat.includes(index)) {
|
||||||
|
setCat([...cat, index])
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setCat(cat.filter(c => c !== index))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyFilter(dataIn, dataOut) {
|
||||||
|
dataIn.forEach(comb_ => {
|
||||||
|
const comb = data.find(d => d.id === comb_.id);
|
||||||
|
if (comb == null)
|
||||||
|
return;
|
||||||
|
if ((country_ === "" || comb.country === country_)
|
||||||
|
&& (gender.H && comb.genre === 'H' || gender.F && comb.genre === 'F' || gender.NA && comb.genre === 'NA')
|
||||||
|
&& (cat.includes(Math.min(CatList.length, CatList.indexOf(comb.categorie) + comb.overCategory)))
|
||||||
|
&& (weightMin === 0 || comb.weight !== null && comb.weight >= weightMin)
|
||||||
|
&& (weightMax === 0 || comb.weight !== null && comb.weight <= weightMax)
|
||||||
|
&& ((comb.teamMembers == null || comb.teamMembers.length === 0) !== team)
|
||||||
|
&& (preset === -1 || comb.categoriesInscrites.includes(preset))) {
|
||||||
|
dataOut.push(comb)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const dispoFiltered = [];
|
||||||
|
if (data != null)
|
||||||
|
applyFilter(data, dispoFiltered);
|
||||||
|
|
||||||
|
const makePoule = (combIn, groups) => {
|
||||||
|
combIn = combIn.sort(() => Math.random() - 0.5);
|
||||||
|
const maxInPoule = Math.ceil(combIn.length / 2);
|
||||||
|
const out = []
|
||||||
|
|
||||||
|
const pa = [];
|
||||||
|
const pb = [];
|
||||||
|
|
||||||
|
let nameA;
|
||||||
|
let nameB;
|
||||||
|
groups.forEach(g => {
|
||||||
|
const existsInCombIn = combIn.some(c => c.id === g.id);
|
||||||
|
if (existsInCombIn) {
|
||||||
|
if ((pa.length === 0 || g.poule === nameA) && pa.length < maxInPoule) {
|
||||||
|
nameA = g.poule || "1";
|
||||||
|
pa.push(g.id);
|
||||||
|
} else if ((pb.length === 0 || g.poule === nameB) && pb.length < maxInPoule) {
|
||||||
|
if (!(nameA === (g.poule || (nameA === "1" ? "2" : "1")))) {
|
||||||
|
nameB = g.poule || (nameA === "1" ? "2" : "1");
|
||||||
|
pb.push(g.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
nameA = nameA || (nameB === "1" ? "2" : "1");
|
||||||
|
nameB = nameB || (nameA === "1" ? "2" : "1");
|
||||||
|
|
||||||
|
if (combIn.length <= 5) {
|
||||||
|
combIn.forEach(c => {
|
||||||
|
if (!pa.includes(c.id))
|
||||||
|
pa.push(c.id)
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
for (const c of combIn) {
|
||||||
|
if (pa.includes(c.id) || pb.includes(c.id))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const club = c.club_str || (c.teamMembers && c.teamMembers[0].club_str) || "";
|
||||||
|
|
||||||
|
const countInPa = pa.filter(p => (p.club_str || (p.teamMembers && p.teamMembers[0].club_str) || "") === club).length;
|
||||||
|
const countInPb = pb.filter(p => (p.club_str || (p.teamMembers && p.teamMembers[0].club_str) || "") === club).length;
|
||||||
|
|
||||||
|
if (pa.length < maxInPoule && (countInPa <= countInPb || pb.length >= maxInPoule)) {
|
||||||
|
pa.push(c.id);
|
||||||
|
} else if (pb.length < maxInPoule) {
|
||||||
|
pb.push(c.id);
|
||||||
|
} else {
|
||||||
|
pa.push(c.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pa.forEach(id => out.push({id: id, poule: nameA}));
|
||||||
|
pb.forEach(id => out.push({id: id, poule: nameB}));
|
||||||
|
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSubmit = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
const toReplace = makePoule(dispoFiltered, groups);
|
||||||
|
setGroups(prev => [...prev.filter(g => !toReplace.some(r => r.id === g.id)), ...toReplace]);
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleReplace = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
const toReplace = makePoule(dispoFiltered, []);
|
||||||
|
setGroups(prev => [...prev.map(g => ({id: g.id, poule: "-"})).filter(g => !toReplace.some(r => r.id === g.id)), ...toReplace]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return <>
|
||||||
|
<div className="modal-header">
|
||||||
|
<h1 className="modal-title fs-5" id="autoCatModalLabel">{t('ajoutAutomatique')}</h1>
|
||||||
|
<button type="button" className="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<div className="modal-body">
|
||||||
|
<div className="d-flex flex-wrap justify-content-around mb-1">
|
||||||
|
<div style={{width: "12em"}}>
|
||||||
|
<label htmlFor="inputState0" className="form-label">{t('pays')}</label>
|
||||||
|
<select id="inputState0" className="form-select" value={country_} onChange={(e) => setCountry_(e.target.value)}>
|
||||||
|
<option value={""}>{t('--Tous--')}</option>
|
||||||
|
{country && Object.keys(country).sort((a, b) => {
|
||||||
|
if (a < b) return -1
|
||||||
|
if (a > b) return 1
|
||||||
|
return 0
|
||||||
|
}).map((key, _) => {
|
||||||
|
return (<option key={key} value={key}>{country[key]}</option>)
|
||||||
|
})}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ListPresetSelect value={preset} onChange={setPreset}/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="d-flex flex-wrap justify-content-around mb-3">
|
||||||
|
<div>
|
||||||
|
<label className="form-label">{t('genre')}</label>
|
||||||
|
<div className="d-flex align-items-center">
|
||||||
|
<div className="form-check" style={{marginRight: '10px'}}>
|
||||||
|
<input className="form-check-input" type="checkbox" id="gridCheck" checked={gender.H}
|
||||||
|
onChange={e => setGender((prev) => {
|
||||||
|
return {...prev, H: e.target.checked}
|
||||||
|
})}/>
|
||||||
|
<label className="form-check-label" htmlFor="gridCheck">{t('genre.h')}</label>
|
||||||
|
</div>
|
||||||
|
<div className="form-check" style={{marginRight: '10px'}}>
|
||||||
|
<input className="form-check-input" type="checkbox" id="gridCheck2" checked={gender.F}
|
||||||
|
onChange={e => setGender((prev) => {
|
||||||
|
return {...prev, F: e.target.checked}
|
||||||
|
})}/>
|
||||||
|
<label className="form-check-label" htmlFor="gridCheck2">{t('genre.f')}</label>
|
||||||
|
</div>
|
||||||
|
<div className="form-check">
|
||||||
|
<input className="form-check-input" type="checkbox" id="gridCheck3" checked={gender.NA}
|
||||||
|
onChange={e => setGender((prev) => {
|
||||||
|
return {...prev, NA: e.target.checked}
|
||||||
|
})}/>
|
||||||
|
<label className="form-check-label" htmlFor="gridCheck3">{t('genre.na')}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label className="form-label">{t('team')}</label>
|
||||||
|
<div className="d-flex align-items-center">
|
||||||
|
<div className="form-check" style={{marginRight: '10px'}}>
|
||||||
|
<input className="form-check-input" type="checkbox" id="gridCheck" checked={team}
|
||||||
|
onChange={e => setTeam(e.target.checked)}/>
|
||||||
|
<label className="form-check-label" htmlFor="gridCheck">{t('team')}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label htmlFor="input5" className="form-label">{t('poids')}</label>
|
||||||
|
<div className="row-cols-sm-auto d-flex align-items-center">
|
||||||
|
<div style={{width: "4.25em"}}><input type="number" className="form-control" id="input5" value={weightMin} min="0"
|
||||||
|
name="999"
|
||||||
|
onChange={e => setWeightMin(Number(e.target.value))}/></div>
|
||||||
|
<div><span>{t('select.à')}</span></div>
|
||||||
|
<div style={{width: "4.25em"}}><input type="number" className="form-control" value={weightMax} min="0" name="999"
|
||||||
|
onChange={e => setWeightMax(Number(e.target.value))}/></div>
|
||||||
|
<div><small>{t('select.msg1')}</small></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="d-flex flex-wrap justify-content-around mb-1">
|
||||||
|
<div className="d-flex flex-wrap mb-3">
|
||||||
|
<label htmlFor="inputState2" className="form-label align-self-center" style={{margin: "0 0.5em 0 0"}}>
|
||||||
|
{t('catégorie')} :
|
||||||
|
</label>
|
||||||
|
{CatList.map((cat_, index) => {
|
||||||
|
return <div key={index} className="input-group"
|
||||||
|
style={{display: "contents"}}>
|
||||||
|
<div className="input-group-text">
|
||||||
|
<input className="form-check-input mt-0" type="checkbox"
|
||||||
|
id={"categoriesInput" + index} checked={cat.includes(index)} aria-label={getCatName(cat_)}
|
||||||
|
onChange={e => setCat_(e, index)}/>
|
||||||
|
<label style={{marginLeft: "0.5em"}} htmlFor={"categoriesInput" + index}>{getCatName(cat_)}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<span>{dispoFiltered.length} {t('combattantsCorrespondentAuxSélectionnés')} {dispoFiltered.length > 10 &&
|
||||||
|
<span style={{color: "red"}}>{t('uneCatégorieNePeutContenirPlusDe10Combattants')}</span>}</span>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div className="modal-footer">
|
||||||
|
<button type="button" className="btn btn-secondary" data-bs-dismiss="modal">{t('fermer')}</button>
|
||||||
|
<button type="submit" className="btn btn-primary" data-bs-dismiss="modal" onClick={handleSubmit}
|
||||||
|
disabled={dispoFiltered.length <= 0 || dispoFiltered.length > 10}>{t('ajouter')}</button>
|
||||||
|
<button type="submit" className="btn btn-warning" data-bs-dismiss="modal" onClick={handleReplace}
|
||||||
|
disabled={dispoFiltered.length <= 0 || dispoFiltered.length > 10}>{t('remplacer')}</button>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
}
|
||||||
@ -21,6 +21,7 @@ import {hasEffectCard, useCards, useCardsDispatch} from "../../../hooks/useCard.
|
|||||||
|
|
||||||
import {ScorePanel} from "./ScoreAndCardPanel.jsx";
|
import {ScorePanel} from "./ScoreAndCardPanel.jsx";
|
||||||
import {ConfirmDialog} from "../../../components/ConfirmDialog.jsx";
|
import {ConfirmDialog} from "../../../components/ConfirmDialog.jsx";
|
||||||
|
import {AutoCatModalContent} from "../../../components/cm/AutoCatModalContent.jsx";
|
||||||
|
|
||||||
const vite_url = import.meta.env.VITE_URL;
|
const vite_url = import.meta.env.VITE_URL;
|
||||||
|
|
||||||
@ -240,6 +241,10 @@ function AddComb({groups, setGroups, removeGroup, menuActions, cat}) {
|
|||||||
disabled={data === null} onClick={() => setModalMode(true)}>{t('ajouterUneTeam')}
|
disabled={data === null} onClick={() => setModalMode(true)}>{t('ajouterUneTeam')}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
<button type="button" className="btn btn-primary mt-3 w-100" data-bs-toggle="modal" data-bs-target="#autoCatModal"
|
||||||
|
disabled={data === null}>{t('ajoutAutomatique')}
|
||||||
|
</button>
|
||||||
|
|
||||||
<div className="modal fade" id="selectCombModal" tabIndex="-1" aria-labelledby="selectCombModalLabel" aria-hidden="true">
|
<div className="modal fade" id="selectCombModal" tabIndex="-1" aria-labelledby="selectCombModalLabel" aria-hidden="true">
|
||||||
<div className="modal-dialog modal-dialog-scrollable modal-lg modal-fullscreen-lg-down">
|
<div className="modal-dialog modal-dialog-scrollable modal-lg modal-fullscreen-lg-down">
|
||||||
<div className="modal-content">
|
<div className="modal-content">
|
||||||
@ -249,6 +254,14 @@ function AddComb({groups, setGroups, removeGroup, menuActions, cat}) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="modal fade" id="autoCatModal" tabIndex="-1" aria-labelledby="autoCatModalLabel" aria-hidden="true">
|
||||||
|
<div className="modal-dialog modal-dialog-scrollable modal-lg modal-fullscreen-lg-down">
|
||||||
|
<div className="modal-content">
|
||||||
|
<AutoCatModalContent data={data} groups={groups} setGroups={setGroups} defaultPreset={cat?.preset?.id || -1}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="modal fade" id="groupeModal" tabIndex="-1">
|
<div className="modal fade" id="groupeModal" tabIndex="-1">
|
||||||
<div className="modal-dialog">
|
<div className="modal-dialog">
|
||||||
<div className="modal-content">
|
<div className="modal-content">
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user