Registration status in progress
This commit is contained in:
@@ -145,7 +145,8 @@ object OpenGotha {
|
|||||||
rating = player.rating,
|
rating = player.rating,
|
||||||
rank = Pairable.parseRank(player.rank),
|
rank = Pairable.parseRank(player.rank),
|
||||||
country = player.country,
|
country = player.country,
|
||||||
club = player.club
|
club = player.club,
|
||||||
|
final = "FIN" == player.registeringStatus
|
||||||
).also {
|
).also {
|
||||||
player.participating.toString().forEachIndexed { i,c ->
|
player.participating.toString().forEachIndexed { i,c ->
|
||||||
if (c == '0') it.skip.add(i + 1)
|
if (c == '0') it.skip.add(i + 1)
|
||||||
@@ -215,7 +216,9 @@ object OpenGotha {
|
|||||||
player.displayRank()
|
player.displayRank()
|
||||||
}" rating="${
|
}" rating="${
|
||||||
player.rating
|
player.rating
|
||||||
}" ratingOrigin="" registeringStatus="FIN" smmsCorrection="0"/>"""
|
}" ratingOrigin="" registeringStatus="${
|
||||||
|
if (player.final) "FIN" else "PRE"
|
||||||
|
}" smmsCorrection="0"/>"""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</Players>
|
</Players>
|
||||||
|
@@ -7,10 +7,10 @@ import java.util.*
|
|||||||
|
|
||||||
// Pairable
|
// Pairable
|
||||||
|
|
||||||
sealed class Pairable(val id: ID, val name: String, open val rating: Int, open val rank: Int) {
|
sealed class Pairable(val id: ID, val name: String, open val rating: Int, open val rank: Int, val final: Boolean) {
|
||||||
companion object {
|
companion object {
|
||||||
val MIN_RANK: Int = -30 // 30k
|
const val MIN_RANK: Int = -30 // 30k
|
||||||
val MAX_RANK: Int = 8 // 9D
|
const val MAX_RANK: Int = 8 // 9D
|
||||||
}
|
}
|
||||||
abstract fun toJson(): Json.Object
|
abstract fun toJson(): Json.Object
|
||||||
abstract fun toMutableJson(): Json.MutableObject
|
abstract fun toMutableJson(): Json.MutableObject
|
||||||
@@ -26,7 +26,7 @@ sealed class Pairable(val id: ID, val name: String, open val rating: Int, open v
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object ByePlayer: Pairable(0, "bye", 0, Int.MIN_VALUE) {
|
object ByePlayer: Pairable(0, "bye", 0, Int.MIN_VALUE, true) {
|
||||||
override fun toJson(): Json.Object {
|
override fun toJson(): Json.Object {
|
||||||
throw Error("bye player should never be serialized")
|
throw Error("bye player should never be serialized")
|
||||||
}
|
}
|
||||||
@@ -70,8 +70,9 @@ class Player(
|
|||||||
rating: Int,
|
rating: Int,
|
||||||
rank: Int,
|
rank: Int,
|
||||||
override var country: String,
|
override var country: String,
|
||||||
override var club: String
|
override var club: String,
|
||||||
): Pairable(id, name, rating, rank) {
|
final: Boolean
|
||||||
|
): Pairable(id, name, rating, rank, final) {
|
||||||
companion object
|
companion object
|
||||||
// used to store external IDs ("FFG" => FFG ID, "EGF" => EGF PIN, "AGA" => AGA ID ...)
|
// used to store external IDs ("FFG" => FFG ID, "EGF" => EGF PIN, "AGA" => AGA ID ...)
|
||||||
val externalIds = mutableMapOf<DatabaseId, String>()
|
val externalIds = mutableMapOf<DatabaseId, String>()
|
||||||
@@ -82,7 +83,8 @@ class Player(
|
|||||||
"rating" to rating,
|
"rating" to rating,
|
||||||
"rank" to rank,
|
"rank" to rank,
|
||||||
"country" to country,
|
"country" to country,
|
||||||
"club" to club
|
"club" to club,
|
||||||
|
"final" to final
|
||||||
).also { json ->
|
).also { json ->
|
||||||
if (skip.isNotEmpty()) json["skip"] = Json.Array(skip)
|
if (skip.isNotEmpty()) json["skip"] = Json.Array(skip)
|
||||||
externalIds.forEach { (dbid, id) ->
|
externalIds.forEach { (dbid, id) ->
|
||||||
@@ -103,7 +105,8 @@ fun Player.Companion.fromJson(json: Json.Object, default: Player? = null) = Play
|
|||||||
rating = json.getInt("rating") ?: default?.rating ?: badRequest("missing rating"),
|
rating = json.getInt("rating") ?: default?.rating ?: badRequest("missing rating"),
|
||||||
rank = json.getInt("rank") ?: default?.rank ?: badRequest("missing rank"),
|
rank = json.getInt("rank") ?: default?.rank ?: badRequest("missing rank"),
|
||||||
country = json.getString("country") ?: default?.country ?: badRequest("missing country"),
|
country = json.getString("country") ?: default?.country ?: badRequest("missing country"),
|
||||||
club = json.getString("club") ?: default?.club ?: badRequest("missing club")
|
club = json.getString("club") ?: default?.club ?: badRequest("missing club"),
|
||||||
|
final = json.getBoolean("final") ?: default?.final ?: true
|
||||||
).also { player ->
|
).also { player ->
|
||||||
player.skip.clear()
|
player.skip.clear()
|
||||||
json.getArray("skip")?.let {
|
json.getArray("skip")?.let {
|
||||||
|
@@ -128,7 +128,7 @@ class TeamTournament(
|
|||||||
override val players = mutableMapOf<ID, Player>()
|
override val players = mutableMapOf<ID, Player>()
|
||||||
val teams: MutableMap<ID, Team> = _pairables
|
val teams: MutableMap<ID, Team> = _pairables
|
||||||
|
|
||||||
inner class Team(id: ID, name: String): Pairable(id, name, 0, 0) {
|
inner class Team(id: ID, name: String, final: Boolean): Pairable(id, name, 0, 0, final) {
|
||||||
val playerIds = mutableSetOf<ID>()
|
val playerIds = mutableSetOf<ID>()
|
||||||
val teamPlayers: Set<Player> get() = playerIds.mapNotNull { players[id] }.toSet()
|
val teamPlayers: Set<Player> get() = playerIds.mapNotNull { players[id] }.toSet()
|
||||||
override val rating: Int get() = if (teamPlayers.isEmpty()) super.rating else (teamPlayers.sumOf { player -> player.rating.toDouble() } / players.size).roundToInt()
|
override val rating: Int get() = if (teamPlayers.isEmpty()) super.rating else (teamPlayers.sumOf { player -> player.rating.toDouble() } / players.size).roundToInt()
|
||||||
@@ -146,7 +146,8 @@ class TeamTournament(
|
|||||||
|
|
||||||
fun teamFromJson(json: Json.Object, default: TeamTournament.Team? = null) = Team(
|
fun teamFromJson(json: Json.Object, default: TeamTournament.Team? = null) = Team(
|
||||||
id = json.getInt("id") ?: default?.id ?: Store.nextPlayerId,
|
id = json.getInt("id") ?: default?.id ?: Store.nextPlayerId,
|
||||||
name = json.getString("name") ?: default?.name ?: badRequest("missing name")
|
name = json.getString("name") ?: default?.name ?: badRequest("missing name"),
|
||||||
|
final = json.getBoolean("final") ?: default?.final ?: badRequest("missing final")
|
||||||
).apply {
|
).apply {
|
||||||
json.getArray("players")?.let { arr ->
|
json.getArray("players")?.let { arr ->
|
||||||
arr.mapTo(playerIds) {
|
arr.mapTo(playerIds) {
|
||||||
|
@@ -143,6 +143,35 @@
|
|||||||
|
|
||||||
#player.popup {
|
#player.popup {
|
||||||
min-width: 65vw;
|
min-width: 65vw;
|
||||||
|
#final-reg {
|
||||||
|
.final {
|
||||||
|
color: green;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
&.final {
|
||||||
|
.preliminary {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.final {
|
||||||
|
display: initial;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
td.reg-status {
|
||||||
|
.final {
|
||||||
|
color: green;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
&.final {
|
||||||
|
.final {
|
||||||
|
display: initial;
|
||||||
|
}
|
||||||
|
.preliminary {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pairing section */
|
/* pairing section */
|
||||||
|
@@ -67,13 +67,17 @@ function parseRank(rank) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function fillPlayer(player) {
|
function fillPlayer(player) {
|
||||||
|
// hack UK / GB
|
||||||
|
let country = player.country.toLowerCase();
|
||||||
|
if ('uk' === country) country = 'gb';
|
||||||
let form = $('#player-form')[0];
|
let form = $('#player-form')[0];
|
||||||
form.val('name', player.name);
|
form.val('name', player.name);
|
||||||
form.val('firstname', player.firstname);
|
form.val('firstname', player.firstname);
|
||||||
form.val('country', player.country.toLowerCase());
|
form.val('country', country);
|
||||||
form.val('club', player.club);
|
form.val('club', player.club);
|
||||||
form.val('rank', parseRank(player.rank));
|
form.val('rank', parseRank(player.rank));
|
||||||
form.val('rating', player.rating);
|
form.val('rating', player.rating);
|
||||||
|
form.val('final', false);
|
||||||
$('#needle')[0].value = '';
|
$('#needle')[0].value = '';
|
||||||
initSearch();
|
initSearch();
|
||||||
$('#register').focus();
|
$('#register').focus();
|
||||||
@@ -90,8 +94,10 @@ onLoad(() => {
|
|||||||
$('#add').on('click', e => {
|
$('#add').on('click', e => {
|
||||||
let form = $('#player-form')[0];
|
let form = $('#player-form')[0];
|
||||||
form.addClass('add');
|
form.addClass('add');
|
||||||
// $('#player-form input.participation').forEach(chk => chk.checked = true);
|
// keep preliminary/final status
|
||||||
|
let status = form.val('final') || false;
|
||||||
form.reset();
|
form.reset();
|
||||||
|
form.val('final', status);
|
||||||
$('#player').removeClass('edit').addClass('create');
|
$('#player').removeClass('edit').addClass('create');
|
||||||
modal('player');
|
modal('player');
|
||||||
$('#needle').focus();
|
$('#needle').focus();
|
||||||
@@ -131,7 +137,8 @@ onLoad(() => {
|
|||||||
rank: form.val('rank'),
|
rank: form.val('rank'),
|
||||||
country: form.val('country'),
|
country: form.val('country'),
|
||||||
club: form.val('club'),
|
club: form.val('club'),
|
||||||
skip: form.find('input.participation').map((input,i) => [i+1, input.checked]).filter(arr => !arr[1]).map(arr => arr[0])
|
skip: form.find('input.participation').map((input,i) => [i+1, input.checked]).filter(arr => !arr[1]).map(arr => arr[0]),
|
||||||
|
final: form.val('final')
|
||||||
}
|
}
|
||||||
if (form.hasClass('add')) {
|
if (form.hasClass('add')) {
|
||||||
api.postJson(`tour/${tour_id}/part`, player)
|
api.postJson(`tour/${tour_id}/part`, player)
|
||||||
@@ -152,6 +159,8 @@ onLoad(() => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
$('#players > tbody > tr').on('click', e => {
|
$('#players > tbody > tr').on('click', e => {
|
||||||
|
let regStatus = e.target.closest('td.reg-status');
|
||||||
|
if (regStatus) return;
|
||||||
let id = e.target.closest('tr').attr('data-id');
|
let id = e.target.closest('tr').attr('data-id');
|
||||||
api.getJson(`tour/${tour_id}/part/${id}`)
|
api.getJson(`tour/${tour_id}/part/${id}`)
|
||||||
.then(player => {
|
.then(player => {
|
||||||
@@ -164,6 +173,9 @@ onLoad(() => {
|
|||||||
form.val('rank', player.rank);
|
form.val('rank', player.rank);
|
||||||
form.val('country', player.country);
|
form.val('country', player.country);
|
||||||
form.val('club', player.club);
|
form.val('club', player.club);
|
||||||
|
form.val('final', player.final);
|
||||||
|
if (player.final) $('#final-reg').addClass('final');
|
||||||
|
else $('#final-reg').removeClass('final');
|
||||||
for (r = 1; r <= tour_rounds; ++r) {
|
for (r = 1; r <= tour_rounds; ++r) {
|
||||||
form.val(`r${r}`, !(player.skip && player.skip.includes(r)));
|
form.val(`r${r}`, !(player.skip && player.skip.includes(r)));
|
||||||
}
|
}
|
||||||
@@ -210,4 +222,44 @@ onLoad(() => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
$('#reg-status').on('click', e => {
|
||||||
|
let current = $('#final-reg').hasClass('final');
|
||||||
|
if (current) {
|
||||||
|
$('input[name="final"]')[0].value = false;
|
||||||
|
$('#final-reg').removeClass('final');
|
||||||
|
} else {
|
||||||
|
$('input[name="final"]')[0].value = true;
|
||||||
|
$('#final-reg').addClass('final');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$('.reg-status').on('click', e => {
|
||||||
|
let cell = e.target.closest('td');
|
||||||
|
let tr = e.target.closest('tr');
|
||||||
|
let id = tr.data('id');
|
||||||
|
let newStatus = !cell.hasClass('final');
|
||||||
|
api.putJson(`tour/${tour_id}/part/${id}`, {
|
||||||
|
id: id,
|
||||||
|
final: newStatus
|
||||||
|
}).then(player => {
|
||||||
|
if (player !== 'error') {
|
||||||
|
cell.toggleClass('final');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
e.preventDefault();
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
$('#filter').on('input', (e) => {
|
||||||
|
let input = e.target;
|
||||||
|
let value = input.value.toUpperCase();
|
||||||
|
if (value === '') $('tbody > tr').removeClass('hidden');
|
||||||
|
else $('tbody > tr').forEach(tr => {
|
||||||
|
let txt = tr.data('text');
|
||||||
|
if (txt && txt.indexOf(value) === -1) tr.addClass('hidden');
|
||||||
|
else tr.removeClass('hidden');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
$('#filter-box i').on('click', e => {
|
||||||
|
$('#filter')[0].value = '';
|
||||||
|
$('tbody > tr').removeClass('hidden');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@@ -18,6 +18,7 @@ function setResult(id, result) {
|
|||||||
}
|
}
|
||||||
let resultCell = row.find('td.result');
|
let resultCell = row.find('td.result');
|
||||||
resultCell.text(dispResult).data('result', result);
|
resultCell.text(dispResult).data('result', result);
|
||||||
|
standingsUpToDate = false;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@@ -1,10 +1,18 @@
|
|||||||
<div class="tab-content" id="registration-tab">
|
<div class="tab-content" id="registration-tab">
|
||||||
<div id="reg-view">
|
<div id="reg-view">
|
||||||
|
<div>
|
||||||
|
<div id="filter-box" class="ui icon input">
|
||||||
|
<input type="text" id="filter" placeholder="Search..."/>
|
||||||
|
<i class="circular times link icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="players-list" class="roundbox">
|
<div id="players-list" class="roundbox">
|
||||||
#set($parts = $api.get("tour/${params.id}/part"))
|
#set($parts = $api.get("tour/${params.id}/part"))
|
||||||
#set($pmap = $utils.toMap($parts))
|
#set($pmap = $utils.toMap($parts))
|
||||||
<table id="players" class="ui celled selectable striped table">
|
<table id="players" class="ui celled selectable striped table">
|
||||||
<thead>
|
<thead>
|
||||||
|
<th>Reg</th>
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
<th>First name</th>
|
<th>First name</th>
|
||||||
<th>Country</th>
|
<th>Country</th>
|
||||||
@@ -15,10 +23,14 @@
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
#foreach($part in $parts)
|
#foreach($part in $parts)
|
||||||
<tr data-id="$part.id">
|
<tr data-id="$part.id" data-text="$esc.html("$part.name.toUpperCase() $part.firstname.toUpperCase() $part.club.toUpperCase()")">
|
||||||
|
<td class="centered reg-status #if($part.final)final#end">
|
||||||
|
<span class="preliminary"><i class="fa fa-question"></i></span>
|
||||||
|
<span class="final"><i class="fa fa-check"></i></span>
|
||||||
|
</td>
|
||||||
<td>$part.name</td>
|
<td>$part.name</td>
|
||||||
<td>$part.firstname</td>
|
<td>$part.firstname</td>
|
||||||
<td>$part.country</td>
|
<td>$part.country.toUpperCase()</td>
|
||||||
<td>$part.club</td>
|
<td>$part.club</td>
|
||||||
<td data-sort="$part.rank">#rank($part.rank)</td>
|
<td data-sort="$part.rank">#rank($part.rank)</td>
|
||||||
<td>$part.rating</td>
|
<td>$part.rating</td>
|
||||||
@@ -141,6 +153,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="inline fields">
|
<div class="inline fields">
|
||||||
|
<label>Final ?</label>
|
||||||
|
<div id="final-reg" class="field">
|
||||||
|
<input name="final" type="hidden"/>
|
||||||
|
<button id="reg-status" type="button" class="ui icon roundedremove mini button">
|
||||||
|
<span class="final"><i class="fa fa-check"></i></span>
|
||||||
|
<span class="preliminary"><i class="fa fa-question"></i></span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
<label>Participation</label>
|
<label>Participation</label>
|
||||||
#foreach($r in [1..$tour.rounds])
|
#foreach($r in [1..$tour.rounds])
|
||||||
<div class="centered field">
|
<div class="centered field">
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
<th>result</th>
|
<th>result</th>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
#set($dispRst = {'?':'?', 'w':'w+', 'b':'b+', '=':'=', 'X':'X', '#':'1-1', '0':'0-0'})
|
#set($dispRst = {'?':'?', 'w':'1-0', 'b':'0-1', '=':'½-½', 'X':'X', '#':'1-1', '0':'0-0'})
|
||||||
#foreach($game in $games)
|
#foreach($game in $games)
|
||||||
#set($white = $pmap[$game.w])
|
#set($white = $pmap[$game.w])
|
||||||
#set($black = $pmap[$game.b])
|
#set($black = $pmap[$game.b])
|
||||||
|
@@ -73,6 +73,7 @@
|
|||||||
const tour_id = ${tour.id};
|
const tour_id = ${tour.id};
|
||||||
const tour_rounds = ${tour.rounds};
|
const tour_rounds = ${tour.rounds};
|
||||||
let activeRound = ${round};
|
let activeRound = ${round};
|
||||||
|
let standingsUpToDate = true;
|
||||||
// $params
|
// $params
|
||||||
#end
|
#end
|
||||||
#set($datepickerLocale = $translate.datepickerLocale($request.lang, $request.loc))
|
#set($datepickerLocale = $translate.datepickerLocale($request.lang, $request.loc))
|
||||||
@@ -105,6 +106,9 @@
|
|||||||
$('.step').removeClass('active');
|
$('.step').removeClass('active');
|
||||||
$(`.step[data-step="${step}"], #${step}-tab`).addClass('active');
|
$(`.step[data-step="${step}"], #${step}-tab`).addClass('active');
|
||||||
window.location.hash = `#${step}`;
|
window.location.hash = `#${step}`;
|
||||||
|
if (step === 'standings' && !standingsUpToDate) {
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onLoad(() => {
|
onLoad(() => {
|
||||||
|
Reference in New Issue
Block a user