diff --git a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/api/TournamentHandler.kt b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/api/TournamentHandler.kt index 0134d86..59dd0c9 100644 --- a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/api/TournamentHandler.kt +++ b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/api/TournamentHandler.kt @@ -30,7 +30,9 @@ object TournamentHandler: PairgothApiHandler { if (accept == "application/pairgoth") { it.toFullJson() } else { - it.toJson() + it.toJson().also { json -> + (json as Json.MutableObject)["stats"] = it.stats() + } } } ?: badRequest("no tournament with id #${id}") } diff --git a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/model/Tournament.kt b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/model/Tournament.kt index ca30008..f7ca112 100644 --- a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/model/Tournament.kt +++ b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/model/Tournament.kt @@ -120,6 +120,15 @@ sealed class Tournament ( fun pairedPlayers() = games.flatMap { it.values }.flatMap { listOf(it.black, it.white) }.toSet() fun hasPlayer(dbId: DatabaseId, pId: String) = pId.isNotBlank() && players.values.filter { player -> pId == player.externalIds[dbId] }.isNotEmpty() + + fun stats() = (0..rounds - 1).map { index -> + Json.Object( + "participants" to pairables.values.count { !it.skip.contains(index + 1) }, + "paired" to (games.getOrNull(index)?.values?.flatMap { listOf(it.black, it.white) }?.count { it != 0 } ?: 0), + "games" to (games.getOrNull(index)?.values?.count() ?: 0), + "ready" to (games.getOrNull(index)?.values?.count { it.result != Game.Result.UNKNOWN } ?: 0) + ) + }.toJsonArray() } // standard tournament of individuals @@ -257,7 +266,7 @@ fun Tournament.Companion.fromJson(json: Json.Object, default: Tournament<*>? = n return tournament } -fun Tournament<*>.toJson() = Json.Object( +fun Tournament<*>.toJson() = Json.MutableObject( "id" to id, "type" to type.name, "name" to name, diff --git a/view-webapp/src/main/sass/main.scss b/view-webapp/src/main/sass/main.scss index 652353a..7eae0f5 100644 --- a/view-webapp/src/main/sass/main.scss +++ b/view-webapp/src/main/sass/main.scss @@ -532,11 +532,12 @@ } #title { + position: relative; font-size: 1rem !important; margin-top: 0.1em !important; } - #logo, #lang, .steps, #filter-box, #reglist-mode, #footer, #unpairables, #pairing-buttons, button, #standings-params, #logout, .pairing-stats, .result-sheets, .toggle { + #logo, #lang, .steps, #filter-box, #reglist-mode, #footer, #unpairables, #pairing-buttons, button, #standings-params, #logout, .pairing-stats, .result-sheets, .toggle, #overview { display: none !important; } diff --git a/view-webapp/src/main/sass/tour.scss b/view-webapp/src/main/sass/tour.scss index 24e6ce0..009d011 100644 --- a/view-webapp/src/main/sass/tour.scss +++ b/view-webapp/src/main/sass/tour.scss @@ -16,6 +16,29 @@ font-weight: bold; } + #overview { + position: absolute; + top: 0.2em; + right: 0.5em; + z-index: 2; + button { + line-height: 0.6em; + } + transform: scale(0.65); + } + + #tournament-overview table { + table-layout: fixed; + text-align: center; + border-collapse: collapse; + th, td { + border: solid 1px gray; + } + th { + padding: 0 0.5em; + } + } + /* information section */ form { diff --git a/view-webapp/src/main/webapp/js/tour-results.inc.js b/view-webapp/src/main/webapp/js/tour-results.inc.js index 1baa3dc..04f6c79 100644 --- a/view-webapp/src/main/webapp/js/tour-results.inc.js +++ b/view-webapp/src/main/webapp/js/tour-results.inc.js @@ -24,10 +24,18 @@ function setResult(id, result, previous) { let indicator = $('#known')[0]; let known = parseInt(indicator.innerText); indicator.innerText = ++known; + // and again for overview + indicator = $('#known2')[0]; + known = parseInt(indicator.innerText); + indicator.innerText = ++known; } else if (result === '?') { let indicator = $('#known')[0]; let known = parseInt(indicator.innerText); indicator.innerText = --known; + // and again for overview + indicator = $('#known2')[0]; + known = parseInt(indicator.innerText); + indicator.innerText = --known; } } }) diff --git a/view-webapp/src/main/webapp/tour.html b/view-webapp/src/main/webapp/tour.html index d535365..1c93e46 100644 --- a/view-webapp/src/main/webapp/tour.html +++ b/view-webapp/src/main/webapp/tour.html @@ -32,6 +32,7 @@ #if($tour)

$esc.html($tour.name) +

#end #translate('tour-information.inc.html') @@ -153,6 +154,9 @@ } }); } + $('#overview').on('click', () => { + modal('tournament-overview') + }); }); // ]]# #include('/js/tour-information.inc.js') @@ -174,3 +178,38 @@ vertical-align: initial; } +#if($tour) + +#end \ No newline at end of file