diff --git a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/api/PairingHandler.kt b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/api/PairingHandler.kt index fd2b1b4..f745c8e 100644 --- a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/api/PairingHandler.kt +++ b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/api/PairingHandler.kt @@ -16,6 +16,7 @@ object PairingHandler: PairgothApiHandler { override fun get(request: HttpServletRequest, response: HttpServletResponse): Json? { val tournament = getTournament(request) val round = getSubSelector(request)?.toIntOrNull() ?: badRequest("invalid round number") + if (round > tournament.lastRound() + 1) badRequest("invalid round: previous round has not been played") val playing = tournament.games(round).values.flatMap { listOf(it.black, it.white) }.toSet() diff --git a/view-webapp/src/main/kotlin/org/jeudego/pairgoth/view/ApiTool.kt b/view-webapp/src/main/kotlin/org/jeudego/pairgoth/view/ApiTool.kt index 41c4268..dabcb33 100644 --- a/view-webapp/src/main/kotlin/org/jeudego/pairgoth/view/ApiTool.kt +++ b/view-webapp/src/main/kotlin/org/jeudego/pairgoth/view/ApiTool.kt @@ -6,25 +6,37 @@ import okhttp3.OkHttpClient import okhttp3.Request import okhttp3.RequestBody.Companion.toRequestBody import okhttp3.internal.EMPTY_REQUEST +import org.slf4j.LoggerFactory class ApiTool { companion object { const val JSON = "application/json" val apiRoot = System.getProperty("pairgoth.api.external.url")?.let { "${it.removeSuffix("/")}/" } ?: throw Error("no configured API url") + val logger = LoggerFactory.getLogger("api") } private val client = OkHttpClient() private fun prepare(url: String) = Request.Builder().url("$apiRoot$url").header("Accept", JSON) private fun Json.toRequestBody() = toString().toRequestBody(JSON.toMediaType()) private fun Request.Builder.process(): Json { - client.newCall(build()).execute().use { response -> - if (response.isSuccessful) { - when (response.body?.contentType()?.subtype) { - null -> throw Error("null body or content type") - "json" -> return Json.parse(response.body!!.string()) ?: throw Error("could not parse json") - else -> throw Error("unhandled content type: ${response.body!!.contentType()}") + try { + return client.newCall(build()).execute().use { response -> + if (response.isSuccessful) { + when (response.body?.contentType()?.subtype) { + null -> throw Error("null body or content type") + "json" -> Json.parse(response.body!!.string()) ?: throw Error("could not parse json") + else -> throw Error("unhandled content type: ${response.body!!.contentType()}") + } + } else { + when (response.body?.contentType()?.subtype) { + "json" -> Json.parse(response.body!!.string()) ?: throw Error("could not parse error json") + else -> throw Error("${response.code} ${response.message}") + } } - } else throw Error("api call failed: ${response.code} ${response.message}") + } + } catch (e: Throwable) { + logger.error("api call failed", e) + return Json.Object("error" to e.message) } } diff --git a/view-webapp/src/main/kotlin/org/jeudego/pairgoth/view/PairgothTool.kt b/view-webapp/src/main/kotlin/org/jeudego/pairgoth/view/PairgothTool.kt new file mode 100644 index 0000000..75a0abf --- /dev/null +++ b/view-webapp/src/main/kotlin/org/jeudego/pairgoth/view/PairgothTool.kt @@ -0,0 +1,11 @@ +package org.jeudego.pairgoth.view + +import com.republicate.kson.Json + +/** + * Generic utilities + */ + +class PairgothTool { + public fun toMap(array: Json.Array) = array.map { ser -> ser as Json.Object }.associateBy { it.getLong("id")!! } +} \ No newline at end of file diff --git a/view-webapp/src/main/sass/tour.scss b/view-webapp/src/main/sass/tour.scss index 684af4a..7e057e0 100644 --- a/view-webapp/src/main/sass/tour.scss +++ b/view-webapp/src/main/sass/tour.scss @@ -164,7 +164,7 @@ max-width: 40vw; border: solid 2px darkgray; border-radius: 5px; - padding-top: 1em; + padding: 1em 0.5em; &:before { position: absolute; content: attr(title); @@ -175,6 +175,21 @@ font-size: smaller; font-weight: bold; } + .listitem { + display: flex; + flex-flow: row nowrap; + justify-content: space-between; + gap: 1em; + cursor: pointer; + user-select: none; + &:hover { + background-color: rgba(50, 50, 50, .2); + } + &.selected { + background-color: rgba(100,200,255,200); + cursor: grab; + } + } } #pairing-buttons { display: flex; diff --git a/view-webapp/src/main/webapp/WEB-INF/tools.xml b/view-webapp/src/main/webapp/WEB-INF/tools.xml index 811a5d3..6d68015 100644 --- a/view-webapp/src/main/webapp/WEB-INF/tools.xml +++ b/view-webapp/src/main/webapp/WEB-INF/tools.xml @@ -4,13 +4,14 @@ + - +Exception