Teams of individual players: Teams composition page ok

This commit is contained in:
Claude Brisson
2025-01-26 01:28:44 +01:00
parent 8f8e23d5b1
commit 169546ae66
15 changed files with 193 additions and 44 deletions

View File

@@ -284,6 +284,21 @@
max-width: max(50vw, 20em);
}
#composition.multi-select .listitem {
cursor: default;
i.icon {
cursor: pointer;
@media (hover: hover) {
display: none;
}
}
&:hover {
i.icon {
display: inline;
}
}
}
/* pairing section */
#pairing-content {
@@ -345,7 +360,7 @@
}
}
}
#pairables {
#pairables, #teams {
margin-bottom: 1em;
}
#paired {
@@ -379,7 +394,7 @@
gap: 1em;
max-width: max(10em, 20vw);
}
#unpairables, #previous_games {
#unpairables, #previous_games, #composition {
display: flex;
flex-flow: column nowrap;
min-height: 10vh;

View File

@@ -124,6 +124,7 @@ Surround winner's name or ½-½ Namen des Gewinners oder 0,5 - 0,5 umrahmen
Signature: Unterschrift:
Swiss Schweizer System
Table Tisch
Teams Teams
Team of 2 individual players Team aus 2 Einzelspielern
Team of 3 individual players Team aus 3 Einzelspielern
Team of 4 individual players Team aus 4 Einzelspielern

View File

@@ -120,6 +120,7 @@ Standings after round Classement après la ronde
Stay in the browser Rester dans le navigateur 
Sudden death Mort subite
Swiss Suisse
Teams Équipes
Team of 2 individual players Équipe de 2 joueurs individuels
Team of 3 individual players Équipe de 3 joueurs individuels
Team of 4 individual players Équipe de 4 joueurs individuels

View File

@@ -124,6 +124,7 @@ Sudden death 서든 데스
Surround winner's name or ½-½ 승자의 이름 또는 0.5 - 0.5을 둘러싸기
Signature: 서명:
Swiss 스위스
Teams 팀
Team of 2 individual players 2인 팀
Team of 3 individual players 3인 팀
Team of 4 individual players 4인 팀

View File

@@ -135,6 +135,8 @@ function hideOpponents() {
onLoad(()=>{
// note - this handler is also in use for lists on Mac Mahon super groups and teams pages
// CB TODO - there is some code cleaning to to around the listitems reuse and events:
// the on('click') method should not define specific behaviors for this page, just dispatch custom events
$('.listitem').on('click', e => {
let listitem = e.target.closest('.listitem');
let box = e.target.closest('.multi-select');
@@ -156,17 +158,23 @@ onLoad(()=>{
if (e.detail === 1) {
// single click
focused = listitem.toggleClass('selected').attr('draggable', listitem.hasClass('selected'));
if (box.getAttribute('id') === 'pairables') showOpponents(focused)
} else if (listitem.closest('#pairing-lists')) {
// on pairing page
if (listitem.closest('#paired')) {
// double click
hideOpponents()
focused = listitem.attr('draggable', listitem.hasClass('selected'));
editGame(focused);
} else if (listitem.closest('#pairables')) {
editPairable(focused);
if (box.getAttribute('id') === 'pairables') {
if (focused.hasClass('selected')) showOpponents(focused);
else hideOpponents();
}
} else {
if (listitem.closest('#pairing-lists')) {
// on pairing page
if (listitem.closest('#paired')) {
// double click
hideOpponents()
focused = listitem.attr('draggable', listitem.hasClass('selected'));
editGame(focused);
} else if (listitem.closest('#pairables')) {
editPairable(focused);
}
}
box.dispatchEvent(new CustomEvent('listitem-dblclk', { 'detail': parseInt(listitem.data('id')) }));
}
}
box.dispatchEvent(new CustomEvent('listitems'));

View File

@@ -105,6 +105,11 @@ function parseRank(rank) {
return '';
}
function displayRank(rank) {
rank = parseInt(rank);
return rank < 0 ? `${-rank}k` : `${rank + 1}d`;
}
function fillPlayer(player) {
// hack UK / GB
let country = player.country.toLowerCase();

View File

@@ -24,6 +24,44 @@ function split(teams) {
});
}
function join(players, team) {
console.log(team)
console.log(teams.get(team))
api.putJson(`tour/${tour_id}/team/${team}`, {
"players": teams.get(team).players.concat(players)
}).then(rst => {
if (rst !== 'error') {
document.location.reload();
}
});
}
function leave(teamId, playerId) {
let team = teams.get(teamId);
let index = team.players.indexOf(playerId);
if (index > -1) {
team.players.splice(index, 1);
api.putJson(`tour/${tour_id}/team/${teamId}`, {
"players": team.players
}).then(rst => {
if (rst !== 'error') {
document.location.reload();
}
});
}
}
function showTeam(teamId) {
let team = teams.get(teamId);
$('#composition')[0].clearChildren();
$('#composition').attr('title', team.name).removeClass('hidden');
$('#composition').data('id', teamId);
for (i = 0; i < team.players.length; ++i) {
let listitem = `<div data-id="${team.players[i]}" class="listitem"><span>${team.names[i]}</span><span>${displayRank(team.ranks[i])}&nbsp;<i class="ui red sign out icon"></i></span></div>`
$('#composition')[0].insertAdjacentHTML('beforeend', listitem);
}
}
onLoad(() => {
$('#teamup').on('click', e => {
let rows = $('#teamables .selected.listitem')
@@ -39,14 +77,65 @@ onLoad(() => {
let teams = rows.map(item => parseInt(item.data("id")));
if (teams.length !== 0) split(teams);
});
$('#teamables').on('listitems', () => {
$('#join').on('click', e => {
let rows = $('#teamables .selected.listitem');
if (rows.length === teamSize) {
$('#team-name')[0].value = rows.map(row => row.data('name')).join('-');
$('#teamup').removeClass('disabled');
} else {
$('#team-name')[0].value = '';
$('#teamup').addClass('disabled');
let players = rows.map(item => parseInt(item.data("id")));
let teams = $('#teams .selected.listitem');
if (players.length !== 0 && teams.length === 1) {
join(players, parseInt(teams[0].data("id")));
}
});
});
$('#team-name').on('input', () => {
if ($('#team-name')[0].value === '') {
$('#teamup').addClass('disabled');
} else if ($('#teamables .selected.listitem').length > 0) {
$('#teamup').removeClass('disabled');
}
$('#team-name').data('manual', true);
});
$('#teamables, #teams').on('listitems', () => {
let players = $('#teamables .selected.listitem');
let teams = $('#teams .selected.listitem');
if (players.length === 0) {
$('#teamup').addClass('disabled');
$('#join').addClass('disabled');
if(!$('#team-name').data('manual')) {
$('#team-name')[0].value = '';
}
} else {
if(!$('#team-name').data('manual')) {
$('#team-name')[0].value = players.map(row => row.data('name')).join('-');
}
if ($('#team-name')[0].value !== '') {
$('#teamup').removeClass('disabled');
}
if (teams.length === 1) {
$('#join').removeClass('disabled');
} else {
$('#join').addClass('disabled');
}
}
if (teams.length === 0) {
$('#split').addClass('disabled');
$('#composition').addClass('hidden');
} else {
$('#split').removeClass('disabled');
if (focused && focused.closest('.multi-select').attr('id') === 'teams') {
showTeam(parseInt(focused.data('id')));
}
}
});
/* If we want double-click...
$('#teams').on('listitem-dblclk', e => {
console.log(teams.get(e.detail));
});
*/
$('#composition').on('click', e => {
console.log('click')
if (e.target.matches('.listitem i')) {
let team = parseInt(e.target.closest('.multi-select').data('id'));
let player = parseInt(e.target.closest('.listitem').data('id'));
leave(team, player);
}
});
});

View File

@@ -71,12 +71,10 @@
<option value="PAIRGO" #if($tour && $tour.type == 'PAIRGO') selected #end>Pair-go tournament</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>
#* TODO
<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="TEAM4" #if($tour && $tour.type == 'TEAM4') selected #end>Team of 4 individual players</option>
<option value="TEAM5" #if($tour && $tour.type == 'TEAM5') selected #end>Team of 5 individual players</option>
*#
</select>
</div>
<div class="right four wide field">

View File

@@ -1,7 +1,9 @@
#set($parts = $api.get("tour/${params.id}/part"))
#if($tour.type == 'INDIVIDUAL' || $tour.type.startsWith('TEAM'))
#if($tour.type == 'INDIVIDUAL')
## Standard tournament
#set($pmap = $utils.toMap($parts))
#else
## Pairgo, rengo and teams of individuals
#set($teams = $api.get("tour/${params.id}/team"))
#set($pmap = $utils.toMap($teams))
#end

View File

@@ -18,17 +18,32 @@
Team up
</button>
</div>
<button id="split" class="ui orange right labeled icon floating button">
<button id="join" class="ui green right labeled icon floating disabled button">
<i class="chevron right icon"></i>
Join
</button>
<button id="split" class="ui orange right labeled icon floating disabled button">
<i class="angle double left icon"></i>
Split
</button>
</div>
<div id="teams" class="multi-select" title="teams">
<div>
<div id="teams" class="multi-select" title="teams">
#foreach($team in $teams)
<div data-id="$team.id" class="listitem team"><span class="name">$team.name</span><span>#rank($team.rank)#if($team.country) $team.country#end</span></div>
<div data-id="$team.id" class="listitem team"><span class="name">$team.name</span><span>#rank($team.rank)#if($team.country) $team.country#end</span></div>
#end
</div>
<div id="composition" class="hidden multi-select" title="">
</div>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript">
// XXXXXX
// $teams.class.name
// $teams
let teams = new Map(${teams}.map(team => [team.id, team]));
</script>