Mac Mahon groups edition

This commit is contained in:
Claude Brisson
2024-01-25 06:43:38 +01:00
parent 6fff3893f2
commit a4b18e0ef1
10 changed files with 150 additions and 11 deletions

View File

@@ -32,7 +32,7 @@ object StandingsHandler: PairgothApiHandler {
fun mmBase(pairable: Pairable): Double { fun mmBase(pairable: Pairable): Double {
if (tournament.pairing !is MacMahon) throw Error("invalid call: tournament is not Mac Mahon") if (tournament.pairing !is MacMahon) throw Error("invalid call: tournament is not Mac Mahon")
return min(max(pairable.rank, tournament.pairing.mmFloor), tournament.pairing.mmBar) + MacMahonSolver.mmsZero return min(max(pairable.rank, tournament.pairing.mmFloor), tournament.pairing.mmBar) + MacMahonSolver.mmsZero + pairable.mmsCorrection
} }
// CB avoid code redundancy with solvers // CB avoid code redundancy with solvers

View File

@@ -58,4 +58,12 @@ class PairgothTool {
} }
return Json.Object("total" to total, "known" to known) return Json.Object("total" to total, "known" to known)
} }
fun getMmsMap(pairables: Collection<Json.Object>) =
pairables.groupBy { pairable -> pairable.getDouble("MMS")?.toLong() }
.mapValues { entry ->
entry.value.sortedByDescending { pairable ->
pairable.getInt("rank")
}
}
} }

View File

@@ -39,7 +39,7 @@
white-space: nowrap; white-space: nowrap;
} }
.red { .darkred {
color: darkred; color: darkred;
} }

View File

@@ -181,6 +181,17 @@
} }
} }
#macmahon-groups {
left: 0;
right: 0;
transform: initial;
max-width: max(90vw, 1200px);
.popup-content {
display: flex;
flex-flow: row wrap;
}
}
/* pairing section */ /* pairing section */
#pairing-content { #pairing-content {
@@ -260,7 +271,7 @@
} }
} }
#pairing-buttons { .pairing-buttons {
display: flex; display: flex;
flex-flow: column nowrap; flex-flow: column nowrap;
justify-content: start; justify-content: start;

View File

@@ -58,6 +58,7 @@ Log in Se connecter
Luc Vannier Luc Vannier Luc Vannier Luc Vannier
MM bar Barre MM MM bar Barre MM
Mac Mahon Mac Mahon Mac Mahon Mac Mahon
Mac Mahon groups Groupes Mac Mahon
MacMahon MacMahon MacMahon MacMahon
Main time Temps principal Main time Temps principal
Max time Temps max Max time Temps max

View File

@@ -162,6 +162,7 @@ function close_modal() {
$('body').removeClass('dimmed'); $('body').removeClass('dimmed');
$(`.popup`).removeClass('shown'); $(`.popup`).removeClass('shown');
store('addingPlayers', false); store('addingPlayers', false);
store('macmahonGroups', false);
} }
function downloadFile(blob, filename) { function downloadFile(blob, filename) {
@@ -177,11 +178,14 @@ function downloadFile(blob, filename) {
onLoad(() => { onLoad(() => {
$('button.close').on('click', e => { $('button.close').on('click', e => {
close_modal();
/* no need to be specific...
let modal = e.target.closest('.popup'); let modal = e.target.closest('.popup');
if (modal) { if (modal) {
modal.removeClass('shown'); modal.removeClass('shown');
$('body').removeClass('dimmed'); $('body').removeClass('dimmed');
} }
*/
}); });
/* commented for now - do we want this? /* commented for now - do we want this?
@@ -267,4 +271,3 @@ onLoad(() => {
} }
}); });

View File

@@ -65,18 +65,18 @@ onLoad(()=>{
} }
}); });
$('#pair').on('click', e => { $('#pair').on('click', e => {
let parts = $('#pairables')[0].childNodes.filter('.selected.listitem').map(item => parseInt(item.data("id"))); let parts = $('#pairables .selected.listitem').map(item => parseInt(item.data("id")));
if (parts.length == 0) { if (parts.length == 0) {
$('#pairables .listitem').addClass('selected'); $('#pairables .listitem').addClass('selected');
parts = $('#pairables')[0].childNodes.filter('.selected.listitem').map(item => parseInt(item.data("id"))); parts = $('#pairables .selected.listitem').map(item => parseInt(item.data("id")));
} }
pair(parts); pair(parts);
}); });
$('#unpair').on('click', e => { $('#unpair').on('click', e => {
let games = $('#paired')[0].childNodes.filter('.selected.listitem').map(item => parseInt(item.data("id"))); let games = $('#paired .selected.listitem').map(item => parseInt(item.data("id")));
if (games.length == 0) { if (games.length == 0) {
$('#paired .listitem').addClass('selected'); $('#paired .listitem').addClass('selected');
games = $('#paired')[0].childNodes.filter('.selected.listitem').map(item => parseInt(item.data("id"))); games = $('#paired .selected.listitem').map(item => parseInt(item.data("id")));
} }
unpair(games); unpair(games);
}); });

View File

@@ -104,6 +104,11 @@ function addPlayers() {
store('addingPlayers', true); store('addingPlayers', true);
} }
function bulkUpdate(players) {
Promise.all(players.map(p => api.putJson(`tour/${tour_id}/part/${p.id}`, p)))
.then((values) => window.location.reload());
}
let tableSort; let tableSort;
onLoad(() => { onLoad(() => {
@@ -314,7 +319,56 @@ onLoad(() => {
$('#filter')[0].value = ''; $('#filter')[0].value = '';
$('tbody > tr').removeClass('hidden'); $('tbody > tr').removeClass('hidden');
}); });
$('#edit-macmahon-groups').on('click', e => {
modal('macmahon-groups');
store('macmahonGroups', true);
});
if (store('addingPlayers')) { if (store('addingPlayers')) {
addPlayers(); addPlayers();
} }
if (store('macmahonGroups')) {
modal('macmahon-groups');
}
// mac mahon groups...
$('#under-to-top').on('click', e => {
let players = $('#under-group .selected').map(item => (
{
id: parseInt(item.data("id")),
mmsCorrection: parseInt(item.data("correction")) + 1
}));
bulkUpdate(players);
});
$('#top-to-under').on('click', e => {
let players = $('#top-group .selected').map(item => (
{
id: parseInt(item.data("id")),
mmsCorrection: parseInt(item.data("correction")) - 1
}));
bulkUpdate(players);
});
$('#top-to-super').on('click', e => {
let players = $('#top-group .selected').map(item => (
{
id: parseInt(item.data("id")),
mmsCorrection: parseInt(item.data("correction")) + 1
}));
bulkUpdate(players);
});
$('#super-to-top').on('click', e => {
let players = $('#super-group .selected').map(item => (
{
id: parseInt(item.data("id")),
mmsCorrection: parseInt(item.data("correction")) - 1
}));
bulkUpdate(players);
});
$('#reset-macmahon-groups').on('click', e => {
let players = $('#macmahon-groups .listitem').map(item => (
{
id: parseInt(item.data("id")),
mmsCorrection: 0
}));
bulkUpdate(players);
});
}); });

View File

@@ -37,7 +37,7 @@
</div> </div>
</div> </div>
<div id="pairing-right"> <div id="pairing-right">
<div id="pairing-buttons"> <div class="pairing-buttons">
<button id="pair" class="ui blue right labeled icon floating button"> <button id="pair" class="ui blue right labeled icon floating button">
<i class="angle double right icon"></i> <i class="angle double right icon"></i>
Pair Pair

View File

@@ -36,7 +36,7 @@
<td>$part.firstname</td> <td>$part.firstname</td>
<td>$part.country.toUpperCase()</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)#if($part.mmsCorrection) ($part.mmsCorrection)#end</td>
<td>$part.rating</td> <td>$part.rating</td>
<td> <td>
#foreach($round in [1..$tour.rounds]) #foreach($round in [1..$tour.rounds])
@@ -58,6 +58,12 @@
<i class="plus icon"></i> <i class="plus icon"></i>
Add player Add player
</button> </button>
#if($tour.pairing.type == 'MAC_MAHON')
<button id="edit-macmahon-groups" class="ui right labeled icon floating button">
<i class="pencil icon"></i>
Mac Mahon groups
</button>
#end
</div> </div>
</div> </div>
</div> </div>
@@ -193,10 +199,66 @@
</form> </form>
</div> </div>
</div> </div>
#if($tour.pairing.type == 'MAC_MAHON')
#set($mmbase = $api.get("tour/${params.id}/standings/0"))
#if($mmbase.isObject() && ($mmbase.error || $mmbase.message))
#if($mmbase.error)
#set($error = $mmbase.error)
#else
#set($error = $mmbase.message)
#end
<script type="text/javascript">
onLoad(() => {
showError("$error")
});
</script>
#set($mmbase = [])
#end
#set($mmsMap = $utils.getMmsMap($mmbase))
<div id="macmahon-groups" class="popup">
<div class="popup-body">
<div class="popup-content">
<div id="under-group" class="multi-select" title="bar-1">
#foreach($part in $mmsMap.get(30 + $tour.pairing.mmBar - 1))
<div data-id="$part.id" data-correction="${part.mmsCorrection|0}" class="listitem pairable"><span>$part.name $part.firstname</span><span>#rank($part.rank) $part.country</span></div>
#end
</div>
<div class="pairing-buttons">
<button id="under-to-top" class="ui blue icon floating button"><i class="angle double right icon"></i></button>
<button id="top-to-under" class="ui orange icon floating button"><i class="angle double left icon"></i></button>
</div>
<div id="top-group" class="multi-select" title="top group">
#foreach($part in $mmsMap.get(30 + $tour.pairing.mmBar))
<div data-id="$part.id" data-correction="${part.mmsCorrection|0}" class="listitem pairable"><span>$part.name $part.firstname</span><span>#rank($part.rank) $part.country</span></div>
#end
</div>
<div class="pairing-buttons">
<button id="top-to-super" class="ui blue icon floating button"><i class="angle double right icon"></i></button>
<button id="super-to-top" class="ui orange icon floating button"><i class="angle double left icon"></i></button>
</div>
<div id="super-group" class="multi-select" title="super group">
#foreach($part in $mmsMap.get(30 + $tour.pairing.mmBar + 1))
<div data-id="$part.id" data-correction="${part.mmsCorrection|0}" class="listitem pairable"><span>$part.name $part.firstname</span><span>#rank($part.rank) $part.country</span></div>
#end
</div>
</div>
<div class="popup-footer">
<button id="close-macmahon-groups" type="button" class="ui gray right labeled icon floating close button">
<i class="times icon"></i>
Close
</button>
<button id="reset-macmahon-groups" type="button" class="ui orange right labeled icon floating button">
<i class="trash icon"></i>
Reset Mac Mahon groups
</button>
</div>
</div>
</div>
#end
#[[ #[[
<script id="result" type="text/template"> <script id="result" type="text/template">
{{for #data}} {{for #data}}
<div class="result-line" data-index="{{:#getIndex()}}">[{{:origin}}] {{:country}} - {{:name}} {{:firstname}} {{:rank}} ({{:club}}) {{if origin === 'FFG' && country === 'FR' license !== 'L'}}<span class="red">non licencié</span>{{/if}}</div> <div class="result-line" data-index="{{:#getIndex()}}">[{{:origin}}] {{:country}} - {{:name}} {{:firstname}} {{:rank}} ({{:club}}) {{if origin === 'FFG' && country === 'FR' license !== 'L'}}<span class="darkred">non licencié</span>{{/if}}</div>
{{/for}} {{/for}}
</script> </script>
<script type="text/javascript" src="/lib/jsrender-1.0.13/jsrender.min.js"></script> <script type="text/javascript" src="/lib/jsrender-1.0.13/jsrender.min.js"></script>