Advanced parameters dialog

This commit is contained in:
Claude Brisson
2024-01-28 08:34:07 +01:00
parent ff7cf47af5
commit f34afaf9b6
9 changed files with 286 additions and 23 deletions

View File

@@ -45,7 +45,7 @@ data class MainCritParams(
val drawUpDownUpperMode: DrawUpDown = DrawUpDown.BOTTOM, val drawUpDownUpperMode: DrawUpDown = DrawUpDown.BOTTOM,
val drawUpDownLowerMode: DrawUpDown = DrawUpDown.TOP, val drawUpDownLowerMode: DrawUpDown = DrawUpDown.TOP,
val seedingWeight: Double = MAX_SEEDING_WEIGHT, // 5 *10^6, opengotha maximizeSeeding val seedingWeight: Double = MAX_SEEDING_WEIGHT, // 5 *10^6, opengotha maximizeSeeding
val lastRoundForSeedSystem1: Int = 1, val lastRoundForSeedSystem1: Int = 2,
val seedSystem1: SeedMethod = SeedMethod.SPLIT_AND_RANDOM, val seedSystem1: SeedMethod = SeedMethod.SPLIT_AND_RANDOM,
val seedSystem2: SeedMethod = SeedMethod.SPLIT_AND_FOLD, val seedSystem2: SeedMethod = SeedMethod.SPLIT_AND_FOLD,
val additionalPlacementCritSystem1: Criterion = Criterion.RATING, val additionalPlacementCritSystem1: Criterion = Criterion.RATING,
@@ -226,6 +226,7 @@ fun BaseCritParams.toJson() = Json.Object(
"nx1" to nx1, "nx1" to nx1,
"dupWeight" to dupWeight, "dupWeight" to dupWeight,
"random" to random, "random" to random,
"deterministic" to deterministic,
"colorBalanceWeight" to colorBalanceWeight "colorBalanceWeight" to colorBalanceWeight
) )

View File

@@ -207,6 +207,26 @@
.step:last-child { padding-right: 1em; } .step:last-child { padding-right: 1em; }
.step .description { display: none; } .step .description { display: none; }
label input[type="checkbox"] {
vertical-align: baseline;
}
.ui.form .inline.fields select, .ui.form label select {
width: initial;
}
.ui.accordion .content {
display: block;
max-height: 0;
overflow-y: hidden;
padding: 0 1em 0 2em;
transition: all 0.5s ease-out;
&.active {
padding: 0.5em 1em 0.5em 2em;
max-height: 600px;
}
}
.ui.form input[type=text], .ui.form input[type="number"], .ui.form select { .ui.form input[type=text], .ui.form input[type="number"], .ui.form select {
padding: 0.4em 0.2em; padding: 0.4em 0.2em;
} }
@@ -228,7 +248,7 @@
background-clip: initial; background-clip: initial;
} }
.ui.form label input[type="checkbox"] { .ui.form label input[type="checkbox"]:not(.inline) {
margin-left: 1em; margin-left: 1em;
vertical-align: baseline; vertical-align: baseline;
} }
@@ -325,6 +345,13 @@
margin: auto; margin: auto;
z-index: 100; z-index: 100;
pointer-events: none; pointer-events: none;
&.wide {
left: 0;
right: 0;
transform: initial;
max-width: max(90vw, 1200px);
width: 90vw;
}
div.close { div.close {
position: absolute; position: absolute;
width: 30px; width: 30px;

View File

@@ -182,10 +182,6 @@
} }
#macmahon-groups { #macmahon-groups {
left: 0;
right: 0;
transform: initial;
max-width: max(90vw, 1200px);
.popup-content { .popup-content {
display: flex; display: flex;
flex-flow: row wrap; flex-flow: row wrap;

View File

@@ -11,6 +11,7 @@
: This mode is the best suited for big Go events like congresses, it allows to register players, enter results and manage pairing from several workstations at once. : Ce mode est le plus adapté pour de grands événements de Go comme les congrès, il permet denregistrer les joueurs, dentrer les résultats et de gérer les appariements depuis plusieurs postes à la fois. : This mode is the best suited for big Go events like congresses, it allows to register players, enter results and manage pairing from several workstations at once. : Ce mode est le plus adapté pour de grands événements de Go comme les congrès, il permet denregistrer les joueurs, dentrer les résultats et de gérer les appariements depuis plusieurs postes à la fois.
: the : le projet : the : le projet
Add player Ajouter Add player Ajouter
Advanced parameters Paramètres avancés
At its core,   At its core,  
Browse Parcourir les sources de Browse Parcourir les sources de
Byo-yomi periods Périodes de byo-yomi Byo-yomi periods Périodes de byo-yomi
@@ -64,6 +65,7 @@ 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
MM floor Plancher MM
Name Nom Name Nom
Nbw NbV Nbw NbV
New Tournament Nouveau Tournoi New Tournament Nouveau Tournoi

View File

@@ -269,5 +269,15 @@ onLoad(() => {
let scroll = $('#center')[0].scrollTop; let scroll = $('#center')[0].scrollTop;
}, 200); }, 200);
} }
$('.accordion .title').on('click', e => {
let accordion = e.target.closest('.accordion');
let title = e.target.closest('.title');
let content = title.nextElementSibling;
if (!title.hasClass('active')) {
accordion.find('.active').removeClass('active');
}
title.toggleClass('active');
content.toggleClass('active');
});
}); });

View File

@@ -15,6 +15,10 @@ onLoad(() => {
return false; return false;
}); });
$('#parameters').on('click', e => {
modal('parameters-modal');
});
$('#validate').on('click', e => { $('#validate').on('click', e => {
let form = e.target.closest('form'); let form = e.target.closest('form');
let valid = true; let valid = true;
@@ -177,13 +181,59 @@ onLoad(() => {
if (typeof(tour_id) !== 'undefined') { if (typeof(tour_id) !== 'undefined') {
api.putJson(`tour/${tour_id}`, tour) api.putJson(`tour/${tour_id}`, tour)
.then(tour => { .then(tour => {
window.location.reload(); if (tour !== 'error') {
window.location.reload();
}
}); });
} else { } else {
api.postJson('tour', tour) api.postJson('tour', tour)
.then(tour => { .then(tour => {
window.location.href += `?id=${tour.id}`; if (tour !== 'error') {
window.location.href += `?id=${tour.id}`;
}
}); });
} }
}); });
$('#update-parameters').on('click', e => {
let form = $('#parameters-form')[0];
let tour = {
pairing: {
base: {
deterministic: form.val('deterministic'),
colorBalanceWeight: form.val('colorBalance') ? 1000000.0 : 0.0 // TODO use client side boolean
},
main: {
mmsValueAbsent: form.val('mmsValueAbsent'),
firstSeedLastRound: form.val('firstSeedLastRound'),
firstSeedAddCrit: form.val('firstSeedAddRating') ? 'RATING' : 'NONE', // TODO use client side boolean
firstSeed: form.val('firstSeed'),
secondSeedAddCrit: form.val('secondSeedAddRating') ? 'RATING' : 'NONE', // TODO use client side boolean
secondSeed: form.val('secondSeed'),
upDownCompensate: form.val('upDownCompoensate'),
upDownUpperMode: form.val('upDownUpperMode'),
upDownLowerMode: form.val('upDownLowerMode')
},
secondary: {
rankThreshold: form.val('rankThreshold'),
winsThreshold: form.val('winsThreshold'),
barThreshold: form.val('barThreshold')
},
geo: {
mmsDiffCountry: form.val('mmsDiffCountry'),
mmsDiffClub: form.val('mmsDiffClub')
},
handicap: {
useMMS: form.val('useMMS'),
ceiling: form.val('ceiling')
}
}
}
console.log(tour);
api.putJson(`tour/${tour_id}`, tour)
.then(tour => {
if (tour !== 'error') {
window.location.reload();
}
});
});
}); });

View File

@@ -44,7 +44,7 @@
<input name="location" type="text" placeholder="tournament location" value="#if($tour)$!tour.location#end"/> <input name="location" type="text" placeholder="tournament location" value="#if($tour)$!tour.location#end"/>
<div class="edit online"> <div class="edit online">
<label> <label>
<input name="online" type="checkbox" #if($tour && $tour.online) checked #end style="vertical-align: baseline;" value="true"/>&nbsp;<b>online tournament</b> <input name="online" type="checkbox" #if($tour && $tour.online) checked #end value="true"/>&nbsp;<b>online tournament</b>
</label> </label>
</div> </div>
</div> </div>
@@ -82,22 +82,20 @@
<option value="ROUND_ROBIN" #if($tour && $tour.pairing.type == 'ROUND_ROBIN') selected #end>Round-robin</option> <option value="ROUND_ROBIN" #if($tour && $tour.pairing.type == 'ROUND_ROBIN') selected #end>Round-robin</option>
</select> </select>
</div> </div>
#* MM floor parameter not shown on creation page
<div class="mms pairing four wide field #if($tour && $tour.pairing.type != 'MAC_MAHON') hidden #end">
<label>MM floor</label>
<span class="info"></span>
<select name="mmFloor">
#set($floor = -20)
#if($tour) #set($floor = $tour.pairing.mmFloor) #end
#levels($floor)
</select>
</div>
*#
<div class="mms pairing four wide field #if($tour && $tour.pairing.type != 'MAC_MAHON') hidden #end"> <div class="mms pairing four wide field #if($tour && $tour.pairing.type != 'MAC_MAHON') hidden #end">
<label>Hd correction</label> <label>Hd correction</label>
<span class="info"></span> <span class="info"></span>
<input name="correction" type="number" min="-9" max="0" value="#if($tour && "$!tour.pairing.handicap.correction" != "")-$tour.pairing.handicap.correction#{else}-1#end"/> <input name="correction" type="number" min="-9" max="0" value="#if($tour && "$!tour.pairing.handicap.correction" != "")-$tour.pairing.handicap.correction#{else}-1#end"/>
</div> </div>
<div class="mms pairing four wide field #if($tour && $tour.pairing.type != 'MAC_MAHON') hidden #end">
<label>MM floor</label>
<span class="info"></span>
<select name="mmFloor">
#set($floor = -20)
#if($tour) #set($floor = $tour.pairing.mmFloor) #end
#levels($floor)
</select>
</div>
<div class="mms pairing four wide field #if($tour && $tour.pairing.type != 'MAC_MAHON') hidden #end"> <div class="mms pairing four wide field #if($tour && $tour.pairing.type != 'MAC_MAHON') hidden #end">
<label>MM bar</label> <label>MM bar</label>
<span class="info"></span> <span class="info"></span>
@@ -215,7 +213,11 @@
<i class="times icon"></i> <i class="times icon"></i>
Close Close
</button> </button>
<button id="export" type="button" class="ui yellow right labeled icon floating button"> <button id="parameters" type="button" class="ui orange right labeled icon floating edit button">
<i class="cogs icon"></i>
Advanced parameters
</button>
<button id="export" type="button" class="ui yellow right labeled icon floating info button">
<i class="download icon"></i> <i class="download icon"></i>
Export Export
</button> </button>
@@ -249,8 +251,28 @@
</div> </div>
<div class="popup-footer"> <div class="popup-footer">
<div class="form-actions"> <div class="form-actions">
<button type="button" class="ui gray floating cancel button">Cancel</button> <button type="button" class="ui gray floating close button">Cancel</button>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
#if($tour)
<div id="parameters-modal" class="wide popup">
<div class="popup-body">
<div class="popup-header">
Advanced parameters
</div>
<div class="popup-content">
#parse('tour-parameters.inc.html')
</div>
<div class="popup-footer">
<div class="form-actions">
<button type="button" class="ui gray floating close button">Cancel</button>
</div>
<div class="form-actions">
<button id="update-parameters" type="button" class="ui green floating button">Update</button>
</div>
</div>
</div>
</div>
#end

View File

@@ -0,0 +1,155 @@
<form id="parameters-form" class="ui edit form">
<div class="ui fluid styled accordion">
<div class="title">
<i class="dropdown icon"></i>
Base parameters
</div>
<div class="content">
<div class="field">
<label><input type="checkbox" name="deterministic" value="true" #if($tour.pairing.base.deterministic) checked #end>&nbsp;deterministic randomness</label>
</div>
<div class="field">
<label><input type="checkbox" name="colorBalance" value="true" #if($tour.pairing.base.colorBalanceWeight) checked #end>&nbsp;balance white and black</label>
</div>
</div>
<div class="title">
<i class="dropdown icon"></i>
Main parameters
</div>
<div class="content">
#if($tour.pairing.type == 'MAC_MAHON')
<div class="inline fields">
<div class="field">
<label>
MMS score for non-played rounds
<select name="mmsValueAbsent">
<option value="0" #if($tour.pairing.main.mmsValueAbsent == 0) selected #end>0</option>
<option value="0.5" #if($tour.pairing.main.mmsValueAbsent == 0.5) selected #end>½</option>
<option value="1" #if($tour.pairing.main.mmsValueAbsent == 1) selected #end>1</option>
</select>
</label>
</div>
</div>
#end
<div class="ui fluid styled accordion">
<div class="title">
<i class="dropdown icon"></i>
Seeding methods inside groups of same score
</div>
<div class="content">
<div class="field">
<label>Apply first seeding method up to round <input type="number" min="1" value="$tour.pairing.main.firstSeedLastRound"/></label>
</div>
<div class="inline fields">
<div class="roundbox field">
<label>First seeding method</label>
<label><input type="checkbox" name="firstSeedAddRating" value="true" #if($tour.pairing.main.firstSeedAddCrit == 'RATING') checked #end/> add a sorting on rating</label>
<select name="firstSeed">
<option value="SPLIT_AND_RANDOM" #if($tour.pairing.main.seedSystem1 == 'SPLIT_AND_RANDOM') selected #end>Split and random</option>
<option value="SPLIT_AND_SLIP" #if($tour.pairing.main.seedSystem1 == 'SPLIT_AND_SLIP') selected #end>Split and slip</option>
<option value="SPLIT_AND_FOLD" #if($tour.pairing.main.seedSystem1 == 'SPLIT_AND_FOLD') selected #end>Split and fold</option>
</select>
</div>
<div class="roundbox field">
<label>Second seeding method</label>
<label><input type="checkbox" name="secondSeedAddRating" value="true" #if($tour.pairing.main.secondSeedAddCrit == 'RATING') checked #end/> add a sorting on rating</label>
<select name="secondSeed">
<option value="SPLIT_AND_RANDOM" #if($tour.pairing.main.seedSystem2 == 'SPLIT_AND_RANDOM') selected #end>Split and random</option>
<option value="SPLIT_AND_SLIP" #if($tour.pairing.main.seedSystem2 == 'SPLIT_AND_SLIP') selected #end>Split and slip</option>
<option value="SPLIT_AND_FOLD" #if($tour.pairing.main.seedSystem2 == 'SPLIT_AND_FOLD') selected #end>Split and fold</option>
</select>
</div>
</div>
</div>
<div class="title">
<i class="dropdown icon"></i>
Draw-up / draw-down between groups of same score
</div>
<div class="content">
<div class="inline fields">
<label><input type="checkbox" name="upDownCompensate" value="true" #if($tour.pairing.main.upDownCompensate) checked #end/> try to compensate a previous draw-up/draw-down by a draw-down/draw-up, then</label>
</div>
<div class="inline fields">
<label>
pair a player in the
<select name="upDownUpperMode">
<option value="TOP" #if($tour.pairing.main.upDownUpperMode == 'TOP') selected #end>top</option>
<option value="MIDDLE" #if($tour.pairing.main.upDownUpperMode == 'MIDDLE') selected #end>middle</option>
<option value="BOTTOM" #if($tour.pairing.main.upDownUpperMode == 'BOTTOM') selected #end>bottom</option>
</select>
of the upper group with a player in the
<select name="upDownLowerMode">
<option value="TOP" #if($tour.pairing.main.upDownLowerMode == 'TOP') selected #end>top</option>
<option value="MIDDLE" #if($tour.pairing.main.upDownLowerMode == 'MIDDLE') selected #end>middle</option>
<option value="BOTTOM" #if($tour.pairing.main.upDownLowerMode == 'BOTTOM') selected #end>bottom</option>
</select>
of the lower group
</label>
</div>
</div>
</div>
</div>
<div class="title">
<i class="dropdown icon"></i>
Secondary parameters
</div>
<div class="content">
<div class="field">
<label>Do not apply secondary criteria for:</label>
<label>
&nbsp;players with a MMS equal to or stronger than
<select name="rankThreshold">
#set($rankThreshold = $tour.pairing.secondary.rankThreshold)
#levels($rankThreshold)
</select>
</label>
<label>
&nbsp;<input name="winsThreshold" type="checkbox" class="inline" value="true" #if($tour.pairing.secondary.winsThreshold) checked #end/>
players who won at least half of their games
</label>
<label>
&nbsp;<input name="barThreshold" type="checkbox" class="inline" value="true" #if($tour.pairing.secondary.barThreshold) checked #end/>
players above the Mac Mahon bar
</label>
</div>
</div>
<div class="title">
<i class="dropdown icon"></i>
Geographical parameters
</div>
<div class="content">
<div class="field">
<label>
Prefer a score gap of
<input type="number" min="0" value="$tour.pairing.geo.mmsDiffCountry"/>
rather than pairing players of the same country.
</label>
</div>
<div class="field">
<label>
Prefer a score gap of
<input type="number" min="0" value="$tour.pairing.geo.mmsDiffClub"/>
rather than pairing players of the same club.
</label>
</div>
</div>
<div class="title">
<i class="dropdown icon"></i>
Handicap parameters
</div>
<div class="content">
<div class="field">
<label>
<input type="checkbox" name="useMMS" value="true" #if($tour.pairing.handicap.useMMS) checked #end/>
use MMS rather than rank for handicap
</label>
</div>
<div class="field">
<label>
Handicap ceiling:
<input name="ceiling" type="number" min="0" class="inline" value="$tour.pairing.handicap.ceiling"/>
</label>
</div>
</div>
</div>
</form>

View File

@@ -215,7 +215,7 @@
#set($mmbase = []) #set($mmbase = [])
#end #end
#set($mmsMap = $utils.getMmsMap($mmbase)) #set($mmsMap = $utils.getMmsMap($mmbase))
<div id="macmahon-groups" class="popup"> <div id="macmahon-groups" class="wide popup">
<div class="popup-body"> <div class="popup-body">
<div class="popup-content"> <div class="popup-content">
<div id="under-group" class="multi-select" title="bar-1"> <div id="under-group" class="multi-select" title="bar-1">