Various bugfixes for teams support

This commit is contained in:
Claude Brisson
2024-04-15 19:50:45 +02:00
parent 179a502bbc
commit 23a4ae37b2
8 changed files with 22 additions and 11 deletions

View File

@@ -147,12 +147,10 @@ object PairingHandler: PairgothApiHandler {
override fun delete(request: HttpServletRequest, response: HttpServletResponse): Json { override fun delete(request: HttpServletRequest, response: HttpServletResponse): Json {
val tournament = getTournament(request) val tournament = getTournament(request)
val round = getSubSelector(request)?.toIntOrNull() ?: badRequest("invalid round number") val round = getSubSelector(request)?.toIntOrNull() ?: badRequest("invalid round number")
// only allow last round (if players have not been paired in the last round, it *may* be possible to be more laxist...)
// Nope
// if (round != tournament.lastRound()) badRequest("cannot delete games in other rounds but the last")
val payload = getArrayPayload(request) val payload = getArrayPayload(request)
val allPlayers = payload.size == 1 && payload[0] == "all" val allPlayers = payload.size == 1 && payload[0] == "all"
if (allPlayers) { if (allPlayers) {
// TODO - just remove this, it is never used ; and no check is done on whether the players are playing...
tournament.games(round).clear() tournament.games(round).clear()
} else { } else {
payload.forEach { payload.forEach {

View File

@@ -161,11 +161,11 @@ ${
"${ "${
player.getString("num")!!.padStart(4, ' ') player.getString("num")!!.padStart(4, ' ')
} ${ } ${
"${player.getString("name")} ${player.getString("firstname")}".padEnd(30, ' ').take(30) "${player.getString("name")} ${player.getString("firstname") ?: ""}".padEnd(30, ' ').take(30)
} ${ } ${
displayRank(player.getInt("rank")!!).uppercase().padStart(3, ' ') displayRank(player.getInt("rank")!!).uppercase().padStart(3, ' ')
} ${ } ${
player.getString("country")!!.uppercase() player.getString("country")?.uppercase() ?: ""
} ${ } ${
(player.getString("club") ?: "").padStart(4).take(4) (player.getString("club") ?: "").padStart(4).take(4)
} ${ } ${
@@ -209,7 +209,7 @@ ${
"${ "${
player.getString("num")!!.padStart(4, ' ') player.getString("num")!!.padStart(4, ' ')
} ${ } ${
"${player.getString("name")} ${player.getString("firstname")}".padEnd(24, ' ').take(24) "${player.getString("name")} ${player.getString("firstname") ?: ""}".padEnd(24, ' ').take(24)
} ${ } ${
displayRank(player.getInt("rank")!!).uppercase().padStart(3, ' ') displayRank(player.getInt("rank")!!).uppercase().padStart(3, ' ')
} ${ } ${
@@ -255,7 +255,7 @@ ${
// lines // lines
lines.forEach { line -> lines.forEach { line ->
writer.println("${ writer.println("${
fields.joinToString(";") { if (it.second) "\"${line[it.first]}\"" else "${line[it.first]}" } fields.joinToString(";") { if (it.second) "\"${line[it.first] ?: ""}\"" else "${line[it.first] ?: ""}" }
};${ };${
line.getArray("results")!!.joinToString(";") line.getArray("results")!!.joinToString(";")
};${ };${

View File

@@ -45,6 +45,9 @@ object TeamHandler: PairgothApiHandler {
val tournament = getTournament(request) val tournament = getTournament(request)
if (tournament !is TeamTournament) badRequest("tournament is not a team tournament") if (tournament !is TeamTournament) badRequest("tournament is not a team tournament")
val id = getSubSelector(request)?.toIntOrNull() ?: badRequest("missing or invalid team selector") val id = getSubSelector(request)?.toIntOrNull() ?: badRequest("missing or invalid team selector")
if (tournament.pairedPlayers().contains(id)) {
badRequest("team is playing");
}
tournament.teams.remove(id) ?: badRequest("invalid team id") tournament.teams.remove(id) ?: badRequest("invalid team id")
tournament.dispatchEvent(TeamDeleted, request, Json.Object("id" to id)) tournament.dispatchEvent(TeamDeleted, request, Json.Object("id" to id))
return Json.Object("success" to true) return Json.Object("success" to true)

View File

@@ -21,7 +21,7 @@ sealed class Pairable(val id: ID, val name: String, val rating: Int, val rank: I
open fun fullName(separator: String = " "): String { open fun fullName(separator: String = " "): String {
return name return name
} }
val skip = mutableSetOf<Int>() // skipped rounds open val skip = mutableSetOf<Int>() // skipped rounds
fun equals(other: Pairable): Boolean { fun equals(other: Pairable): Boolean {
return id == other.id return id == other.id

View File

@@ -196,6 +196,8 @@ class TeamTournament(
club?.also { json["club"] = it } club?.also { json["club"] = it }
} }
val teamOfIndividuals: Boolean get() = type.individual val teamOfIndividuals: Boolean get() = type.individual
override val skip get() = playerIds.map { players[it]!!.skip }.reduce { left, right -> (left union right) as MutableSet<Int> }
} }
fun teamFromJson(json: Json.Object, default: TeamTournament.Team? = null): Team { fun teamFromJson(json: Json.Object, default: TeamTournament.Team? = null): Team {

View File

@@ -117,7 +117,7 @@ onLoad(()=>{
}); });
$('#pair').on('click', e => { $('#pair').on('click', e => {
let parts = $('#pairables .selected.listitem').map(item => parseInt(item.data("id"))); let parts = $('#pairables .selected.listitem').map(item => parseInt(item.data("id")));
if (parts.length) { if (parts.length === 0) {
$('#pairables .listitem').addClass('selected'); $('#pairables .listitem').addClass('selected');
parts = $('#pairables .selected.listitem').map(item => parseInt(item.data("id"))); parts = $('#pairables .selected.listitem').map(item => parseInt(item.data("id")));
} }

View File

@@ -13,10 +13,14 @@ function split(teams) {
let promises = teams.map(team => api.deleteJson(`tour/${tour_id}/team/${team}`)); let promises = teams.map(team => api.deleteJson(`tour/${tour_id}/team/${team}`));
Promise.all(promises) Promise.all(promises)
.then(rsts => { .then(rsts => {
let all = true;
let any = false;
for (let rst of rsts) { for (let rst of rsts) {
all = all && rst.success;
any = any || rst.success;
if (!rst.success) console.error(rst.error) if (!rst.success) console.error(rst.error)
} }
document.location.reload(); if (any) document.location.reload();
}); });
} }
@@ -28,6 +32,10 @@ onLoad(() => {
}); });
$('#split').on('click', e => { $('#split').on('click', e => {
let rows = $('#teams .selected.listitem') let rows = $('#teams .selected.listitem')
if (rows.length == 0) {
$('#teams .listitem').addClass('selected');
rows = $('#teams .selected.listitem');
}
let teams = rows.map(item => parseInt(item.data("id"))); let teams = rows.map(item => parseInt(item.data("id")));
if (teams.length !== 0) split(teams); if (teams.length !== 0) split(teams);
}); });

View File

@@ -63,9 +63,9 @@
<select name="type"> <select name="type">
<option value="INDIVIDUAL" #if(!$tour || $tour.type == 'INDIVIDUAL') selected #end>Individual players</option> <option value="INDIVIDUAL" #if(!$tour || $tour.type == 'INDIVIDUAL') selected #end>Individual players</option>
<option value="PAIRGO" #if($tour && $tour.type == 'PAIRGO') selected #end>Pair-go tournament</option> <option value="PAIRGO" #if($tour && $tour.type == 'PAIRGO') selected #end>Pair-go tournament</option>
#* TODO
<option value="RENGO2" #if($tour && $tour.type == 'RENGO2') selected #end>Rengo with 2 players teams</option> <option value="RENGO2" #if($tour && $tour.type == 'RENGO2') selected #end>Rengo with 2 players teams</option>
<option value="RENGO3" #if($tour && $tour.type == 'RENGO3') selected #end>Rengo with 3 players team</option> <option value="RENGO3" #if($tour && $tour.type == 'RENGO3') selected #end>Rengo with 3 players team</option>
#* TODO
<option value="TEAM2" #if($tour && $tour.type == 'TEAM2') selected #end>Team of 2 individual players</option> <option value="TEAM2" #if($tour && $tour.type == 'TEAM2') selected #end>Team of 2 individual players</option>
<option value="TEAM3" #if($tour && $tour.type == 'TEAM3') selected #end>Team of 3 individual players</option> <option value="TEAM3" #if($tour && $tour.type == 'TEAM3') selected #end>Team of 3 individual players</option>
<option value="TEAM4" #if($tour && $tour.type == 'TEAM4') selected #end>Team of 4 individual players</option> <option value="TEAM4" #if($tour && $tour.type == 'TEAM4') selected #end>Team of 4 individual players</option>