Add a 'final' filter to registration page; coherence check on server for final and skipping
This commit is contained in:
@@ -34,7 +34,18 @@ object PlayerHandler: PairgothApiHandler {
|
||||
val player = tournament.players[id] ?: badRequest("invalid player id")
|
||||
val payload = getObjectPayload(request)
|
||||
val updated = Player.fromJson(payload, player)
|
||||
tournament.players[updated.id] = updated
|
||||
// check coherence
|
||||
if (player.final && !updated.final && tournament.pairedPlayers().contains(updated.id)) {
|
||||
badRequest("player is playing")
|
||||
}
|
||||
val leavingRounds = updated.skip.toSet().minus(player.skip.toSet())
|
||||
leavingRounds.forEach { round ->
|
||||
val playing = tournament.games(round).values.flatMap { listOf(it.black, it.white) }
|
||||
if (playing.contains(id)) {
|
||||
throw badRequest("player is playing in round #$round")
|
||||
}
|
||||
}
|
||||
tournament.players[id] = updated
|
||||
tournament.dispatchEvent(PlayerUpdated, player.toJson())
|
||||
return Json.Object("success" to true)
|
||||
}
|
||||
@@ -42,6 +53,11 @@ object PlayerHandler: PairgothApiHandler {
|
||||
override fun delete(request: HttpServletRequest, response: HttpServletResponse): Json {
|
||||
val tournament = getTournament(request)
|
||||
val id = getSubSelector(request)?.toIntOrNull() ?: badRequest("missing or invalid player selector")
|
||||
// check coherence
|
||||
val player = tournament.players[id] ?: badRequest("invalid player id")
|
||||
if (player.final && tournament.pairedPlayers().contains(id)) {
|
||||
badRequest("player is playing")
|
||||
}
|
||||
tournament.players.remove(id) ?: badRequest("invalid player id")
|
||||
tournament.dispatchEvent(PlayerDeleted, Json.Object("id" to id))
|
||||
return Json.Object("success" to true)
|
||||
|
@@ -114,6 +114,8 @@ sealed class Tournament <P: Pairable>(
|
||||
}
|
||||
return changed
|
||||
}
|
||||
|
||||
fun pairedPlayers() = games.flatMap { it.values }.flatMap { listOf(it.black, it.white) }.toSet()
|
||||
}
|
||||
|
||||
// standard tournament of individuals
|
||||
|
@@ -434,9 +434,14 @@
|
||||
}
|
||||
|
||||
.toggle {
|
||||
display: inline-block;
|
||||
padding-top: 0.2em;
|
||||
display: inline-flex;
|
||||
flex-flow: column nowrap;
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
input {
|
||||
display: none !important;
|
||||
}
|
||||
|
@@ -63,6 +63,9 @@
|
||||
|
||||
#players-list {
|
||||
max-width: 95vw;
|
||||
#players tr.filtered {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
#player {
|
||||
|
@@ -199,7 +199,7 @@ onLoad(() => {
|
||||
switch (e.key) {
|
||||
case 'Escape': {
|
||||
if (tab === '#registration') {
|
||||
if ($('#player').hasClass('shown') && $('#needle')[0].value) {
|
||||
if ($('#player').hasClass('shown') && searchResultShown()) {
|
||||
$('#needle')[0].value = '';
|
||||
initSearch();
|
||||
} else {
|
||||
|
@@ -260,7 +260,7 @@ onLoad(() => {
|
||||
}
|
||||
}
|
||||
}
|
||||
$('.toggle').on('click', e => {
|
||||
$('#search-form .toggle').on('click', e => {
|
||||
let chk = e.target.closest('.toggle');
|
||||
let checkbox = chk.find('input')[0];
|
||||
checkbox.checked = !checkbox.checked;
|
||||
@@ -269,6 +269,16 @@ onLoad(() => {
|
||||
store(id, value);
|
||||
initSearch();
|
||||
});
|
||||
$('#list-header .toggle').on('click', e => {
|
||||
let chk = e.target.closest('.toggle');
|
||||
let checkbox = chk.find('input')[0];
|
||||
checkbox.checked = !checkbox.checked;
|
||||
if (checkbox.checked) {
|
||||
$('td.reg-status:not(.final)').forEach(node => node.parentNode.addClass('filtered'));
|
||||
} else {
|
||||
$('td.reg-status:not(.final)').forEach(node => node.parentNode.removeClass('filtered'));
|
||||
}
|
||||
});
|
||||
document.on('click', e => {
|
||||
let resultLine = e.target.closest('.result-line');
|
||||
if (resultLine) {
|
||||
@@ -320,12 +330,12 @@ onLoad(() => {
|
||||
id: id,
|
||||
final: newStatus
|
||||
}).then(player => {
|
||||
if (player !== 'error') {
|
||||
cell.toggleClass('final');
|
||||
standingsUpToDate = false;
|
||||
pairablesUpToDate = false;
|
||||
}
|
||||
});
|
||||
if (player !== 'error') {
|
||||
cell.toggleClass('final');
|
||||
standingsUpToDate = false;
|
||||
pairablesUpToDate = false;
|
||||
}
|
||||
});
|
||||
e.preventDefault();
|
||||
return false;
|
||||
});
|
||||
|
@@ -3,9 +3,18 @@
|
||||
<div class="tab-content" id="registration-tab">
|
||||
<div id="reg-view">
|
||||
<div id="list-header">
|
||||
<div id="filter-box" class="ui icon input">
|
||||
<input type="text" id="filter" placeholder="Filter..."/>
|
||||
<i class="circular times link icon"></i>
|
||||
<div>
|
||||
<div id="filter-box" class="ui icon input">
|
||||
<input type="text" id="filter" placeholder="Filter..."/>
|
||||
<i class="circular times link icon"></i>
|
||||
</div>
|
||||
<div class="toggle">
|
||||
<input id="filter-final" name="filter-final" type="checkbox"/>
|
||||
<div class="checkbox">
|
||||
<div class="circle"></div>
|
||||
</div>
|
||||
<label>Final</label>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
$parts.size() participants, $utils.countFinals($parts) confirmed.
|
||||
|
Reference in New Issue
Block a user