Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ContestSummaryMenu improvements #1108

Merged
merged 3 commits into from
Aug 26, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -129,14 +129,17 @@ internal class ExecutionStatisticsValues(executionDto: ExecutionDto?) {
* Function that renders Project version label, execution statistics label, pass rate label and rerun button.
* Rerun button is rendered only if [onRerunExecution] is provided.
*
* @param executionDto
* @param executionDto execution that should be used as data source
* @param isContest flag that defines whether to use contest styles or not
* @param classes [ClassName]s that will be applied to highest div
* @param innerClasses [ClassName]s that will be applied to each label
* @param height height of label
* @param onRerunExecution
*/
@Suppress("TOO_MANY_PARAMETERS", "LongParameterList")
fun ChildrenBuilder.displayExecutionInfoHeader(
executionDto: ExecutionDto?,
isContest: Boolean,
classes: String = "",
innerClasses: String = "col flex-wrap m-2",
height: String = "h-100",
Expand All @@ -145,29 +148,32 @@ fun ChildrenBuilder.displayExecutionInfoHeader(
val relativeWidth = onRerunExecution?.let { "min-vw-25" } ?: "min-vw-33"
div {
className = ClassName(classes)
displayProjectVersion(executionDto, "$relativeWidth $innerClasses", height)
displayPassRate(executionDto, "$relativeWidth $innerClasses", height)
displayStatistics(executionDto, "$relativeWidth $innerClasses", height)
displayRerunExecutionButton(executionDto, "$relativeWidth $innerClasses", height, onRerunExecution)
displayProjectVersion(executionDto, isContest, "$relativeWidth $innerClasses", height)
displayPassRate(executionDto, isContest, "$relativeWidth $innerClasses", height)
displayStatistics(executionDto, isContest, "$relativeWidth $innerClasses", height)
displayRerunExecutionButton(executionDto, isContest, "$relativeWidth $innerClasses", height, onRerunExecution)
}
}

/**
* Function that renders Rerun execution button
*
* @param executionDto
* @param executionDto execution that should be used as data source
* @param isContest flag that defines whether to use contest styles or not
* @param classes [ClassName]s that will be applied to highest div
* @param height height of label
* @param onRerunExecution onClick callback
*/
fun ChildrenBuilder.displayRerunExecutionButton(
executionDto: ExecutionDto?,
isContest: Boolean,
classes: String = "",
height: String = "h-100",
onRerunExecution: ((MouseEvent<HTMLAnchorElement, *>) -> Unit)?,
) {
onRerunExecution?.let {
val borderColor = when {
!isContest -> "info"
executionDto == null -> "secondary"
executionDto.status == ExecutionStatus.ERROR || executionDto.failedTests != 0L -> "danger"
executionDto.status == ExecutionStatus.RUNNING || executionDto.status == ExecutionStatus.PENDING -> "info"
Expand Down Expand Up @@ -198,16 +204,19 @@ fun ChildrenBuilder.displayRerunExecutionButton(
/**
* Function that renders label with project version
*
* @param executionDto
* @param executionDto execution that should be used as data source
* @param isContest flag that defines whether to use contest styles or not
* @param classes [ClassName]s that will be applied to highest div
* @param height height of label
*/
fun ChildrenBuilder.displayProjectVersion(
executionDto: ExecutionDto?,
isContest: Boolean,
classes: String = "",
height: String = "h-100",
) {
val statusColor = when {
!isContest -> "bg-info"
executionDto == null -> "bg-secondary"
executionDto.status == ExecutionStatus.ERROR || executionDto.failedTests != 0L -> "bg-danger"
executionDto.status == ExecutionStatus.RUNNING || executionDto.status == ExecutionStatus.PENDING -> "bg-info"
Expand All @@ -233,7 +242,7 @@ fun ChildrenBuilder.displayProjectVersion(
/**
* A function that displays a GIF if tests not found
*
* @param executionDto
* @param executionDto execution that should be used as data source
*/
fun ChildrenBuilder.displayTestNotFound(executionDto: ExecutionDto?) {
val count = executionDto?.allTests
Expand Down Expand Up @@ -266,21 +275,28 @@ fun ChildrenBuilder.displayTestNotFound(executionDto: ExecutionDto?) {
/**
* Function that renders pass rate label
*
* @param executionDto
* @param executionDto execution that should be used as data source
* @param isContest flag that defines whether to use contest styles or not
* @param classes [ClassName]s that will be applied to highest div
* @param height height of label
*/
@Suppress("MAGIC_NUMBER", "TOO_LONG_FUNCTION")
fun ChildrenBuilder.displayPassRate(
executionDto: ExecutionDto?,
isContest: Boolean,
classes: String = "",
height: String = "h-100",
) {
val values = ExecutionStatisticsValues(executionDto)
div {
className = ClassName(classes)
val styles = if (isContest) {
values.style
} else {
"info"
}
div {
className = ClassName("card border-left-${values.style} shadow $height py-2")
className = ClassName("card border-left-$styles shadow $height py-2")
div {
className = ClassName("card-body")
div {
Expand Down Expand Up @@ -333,13 +349,15 @@ fun ChildrenBuilder.displayPassRate(
/**
* Function that renders execution statistics label
*
* @param executionDto
* @param executionDto execution that should be used as data source
* @param isContest flag that defines whether to use contest styles or not
* @param classes [ClassName]s that will be applied to highest div
* @param height height of label
*/
@Suppress("TOO_LONG_FUNCTION", "LongMethod")
fun ChildrenBuilder.displayStatistics(
executionDto: ExecutionDto?,
isContest: Boolean,
classes: String = "",
height: String = "h-100",
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
package com.saveourtool.save.frontend.components.basic.contests

import com.saveourtool.save.entities.ContestResult
import com.saveourtool.save.frontend.components.basic.scoreCard
import com.saveourtool.save.frontend.utils.*

import csstype.*
Expand All @@ -12,6 +11,8 @@ import react.*
import react.dom.html.ReactHTML.a
import react.dom.html.ReactHTML.div
import react.dom.html.ReactHTML.h6
import react.dom.html.ReactHTML.li
import react.dom.html.ReactHTML.ul

import kotlinx.js.jso

Expand All @@ -30,6 +31,72 @@ external interface ContestSummaryMenuProps : Props {
var contestName: String
}

private fun ChildrenBuilder.displayTopProjects(results: List<ContestResult>) {
ul {
className = ClassName("col-10 mb-2 list-group")
displayResult(
"Top position",
"Project",
"Organization",
"Score",
null
)
results.filter {
it.score != null
}
.forEachIndexed { index, contestResult ->
displayResult(
"${index + 1}. ",
contestResult.projectName,
contestResult.organizationName,
contestResult.score.toString(),
"#/${contestResult.organizationName}/${contestResult.projectName}"
)
}
}
}

private fun ChildrenBuilder.displayResult(
topPositionLabel: String,
projectName: String,
organizationName: String,
score: String,
linkToProject: String?,
) {
li {
val disabled = linkToProject?.let { "" } ?: "disabled bg-light"
className = ClassName("list-group-item $disabled")
linkToProject?.let {
a {
href = it
className = ClassName("stretched-link")
}
}
div {
className = ClassName("d-flex justify-content-between")
div {
className = ClassName("row col")
div {
className = ClassName("mr-1 col text-left")
+topPositionLabel
}
div {
className = ClassName("ml-1 col text-center")
+projectName
}
}
div {
className = ClassName("col text-center")
+organizationName
}
div {
className = ClassName("col-1 text-right")
+score
}
}
}
}

/**
* @return ReactElement
*/
Expand Down Expand Up @@ -68,19 +135,8 @@ private fun contestSummaryMenu() = FC<ContestSummaryMenuProps> { props ->
className = ClassName("text-center")
+"There are no participants yet. You can be the first one to participate in it!"
}
}
results.forEach { contestResult ->
div {
className = ClassName("col-10 mb-2")
a {
href = "#/${contestResult.organizationName}/${contestResult.projectName}"
className = ClassName("stretched-link")
}
scoreCard {
name = "${contestResult.organizationName}/${contestResult.projectName}"
contestScore = contestResult.score ?: 0.0
}
}
} else {
displayTopProjects(results)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ class ContestExecutionView : AbstractView<ContestExecutionViewProps, State>(fals
colSpan = tableInstance.columns.size
div {
className = ClassName("row")
displayExecutionInfoHeader(row.original, "row col-11")
displayExecutionInfoHeader(row.original, true, "row col-11")
div {
className = ClassName("col-1")
pieChart(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ class ExecutionView : AbstractView<ExecutionProps, ExecutionState>(false) {
override fun ChildrenBuilder.render() {
div {
div {
displayExecutionInfoHeader(state.executionDto, "row mb-2") { event ->
displayExecutionInfoHeader(state.executionDto, false, "row mb-2") { event ->
scope.launch {
val response = post(
"$apiUrl/run/re-trigger?executionId=${props.executionId}",
Expand Down