|
2 | 2 |
|
3 | 3 | {% set page = "task_submissions" %} |
4 | 4 |
|
| 5 | +{% set score_type = get_score_type(dataset=task.active_dataset) %} |
| 6 | +{% set can_use_tokens = tokens_contest != TOKEN_MODE_DISABLED |
| 7 | + and tokens_task != TOKEN_MODE_DISABLED %} |
| 8 | + |
5 | 9 | {% block additional_js %} |
6 | 10 |
|
7 | 11 | $(document).on("click", "#submission_list tbody tr td.status .details", function (event) { |
|
39 | 43 | } |
40 | 44 | }; |
41 | 45 |
|
42 | | -update_submission_row = function (submission_id, data) { |
| 46 | +/** |
| 47 | + * Update the score (public or tokened) in the UI (both in the task score and in |
| 48 | + * the submission row) given the results of a newly scored submisson |
| 49 | + * |
| 50 | + * score_elem: table cell with the submission score to update. |
| 51 | + * task_score_elem: container element of the task score to update. |
| 52 | + * score (Number): the score of the submission. |
| 53 | + * score_message (String): the score of the submission as a string. |
| 54 | + * task_score (Number): the current score of the task. |
| 55 | + * task_score_message (String): the current score of the task as a string. |
| 56 | + * task_score_is_partial (Boolean): if some submission has yet to be scored. |
| 57 | + * max_score (Number): maximum score of the task. |
| 58 | + */ |
| 59 | +update_score = function(score_elem, task_score_elem, |
| 60 | + score, score_message, |
| 61 | + task_score, task_score_message, task_score_is_partial, |
| 62 | + max_score) { |
| 63 | + // Submission row. |
| 64 | + if (score !== undefined) { |
| 65 | + score_elem.addClass(get_score_class(score, max_score)); |
| 66 | + score_elem.removeClass("undefined"); |
| 67 | + score_elem.text(score_message); |
| 68 | + } |
| 69 | + |
| 70 | + // Task score. |
| 71 | + var task_score_span = task_score_elem.find(".score"); |
| 72 | + task_score_span.text(task_score_message); |
| 73 | + if (task_score_is_partial) { |
| 74 | + task_score_span.append( |
| 75 | + $("<img class=\"details\" src=\"{{ url("static", "loading.gif") }}\"/>")); |
| 76 | + } |
| 77 | + task_score_elem.removeClass("undefined"); |
| 78 | + task_score_elem.removeClass("score_0"); |
| 79 | + task_score_elem.removeClass("score_0_100"); |
| 80 | + task_score_elem.removeClass("score_100"); |
| 81 | + task_score_elem.addClass(get_score_class(task_score, max_score)); |
| 82 | +}; |
| 83 | + |
| 84 | +update_scores = function (submission_id, data) { |
43 | 85 | var row = $("#submission_list tbody tr[data-submission=\"" + submission_id + "\"]"); |
44 | 86 | row.attr("data-status", data["status"]); |
45 | 87 | row.children("td.status").text(data["status_text"]); |
|
52 | 94 | $("<a class=\"details\">{% trans %}details{% endtrans %}</a>")); |
53 | 95 | } |
54 | 96 | if (data["status"] == {{ SubmissionResult.SCORED }}) { |
55 | | - if (data["public_score"] != undefined) { |
56 | | - row.children("td.public_score").addClass(get_score_class(data["public_score"], data["max_public_score"])); |
57 | | - row.children("td.public_score").removeClass("undefined"); |
58 | | - row.children("td.public_score").html(data["public_score_message"]); |
59 | | - } |
60 | | - if (data["score"] != undefined) { |
61 | | - // This element may not exist, if max_public_score == max_score. |
62 | | - row.children("td.total_score").addClass(get_score_class(data["score"], data["max_score"])); |
63 | | - row.children("td.total_score").removeClass("undefined"); |
64 | | - row.children("td.total_score").html(data["score_message"]); |
65 | | - } |
| 97 | + update_score( |
| 98 | + row.children("td.public_score"), $("#task_score_public"), |
| 99 | + data["public_score"], data["public_score_message"], |
| 100 | + data["task_public_score"], data["task_public_score_message"], |
| 101 | + data["task_score_is_partial"], data["max_public_score"]); |
| 102 | +{% if can_use_tokens %} |
| 103 | + update_score( |
| 104 | + row.children("td.total_score"), $("#task_score_tokened"), |
| 105 | + data["score"], data["score_message"], |
| 106 | + data["task_tokened_score"], data["task_tokened_score_message"], |
| 107 | + data["task_score_is_partial"], data["max_score"]); |
| 108 | +{% endif %} |
66 | 109 | } else if (data["status"] != {{ SubmissionResult.COMPILATION_FAILED }}) { |
67 | | - schedule_update_submission_row(submission_id); |
| 110 | + schedule_update_scores(submission_id); |
68 | 111 | } |
69 | 112 | }; |
70 | 113 |
|
71 | | -schedule_update_submission_row = function (submission_id) { |
72 | | - if (typeof(schedule_update_submission_row.delays) === "undefined") { |
73 | | - schedule_update_submission_row.delays = {}; |
| 114 | +schedule_update_scores = function (submission_id) { |
| 115 | + if (typeof(schedule_update_scores.delays) === "undefined") { |
| 116 | + schedule_update_scores.delays = {}; |
74 | 117 | } |
75 | | - if (!schedule_update_submission_row.delays[submission_id]) { |
76 | | - schedule_update_submission_row.delays[submission_id] = 1000.0; |
| 118 | + if (!schedule_update_scores.delays[submission_id]) { |
| 119 | + schedule_update_scores.delays[submission_id] = 1000.0; |
77 | 120 | } else { |
78 | 121 | // We want exponential backoff, but slightly staggered across submissions to |
79 | 122 | // avoid asking about all of them at the same time, so we use 1.4 plus a |
80 | 123 | // value depending on the submission id. |
81 | 124 | var hash = (37 * parseInt(submission_id)) % 100 / 100.0; |
82 | | - schedule_update_submission_row.delays[submission_id] = |
83 | | - schedule_update_submission_row.delays[submission_id] |
| 125 | + schedule_update_scores.delays[submission_id] = |
| 126 | + schedule_update_scores.delays[submission_id] |
84 | 127 | * (1.4 + hash * 0.2); |
85 | 128 | } |
86 | 129 | setTimeout(function () { |
87 | 130 | $.get(utils.contest_url("tasks", "{{ task.name }}", "submissions", submission_id), function (data) { |
88 | | - update_submission_row(submission_id, data); |
| 131 | + update_scores(submission_id, data); |
89 | 132 | }); |
90 | | - }, schedule_update_submission_row.delays[submission_id]); |
| 133 | + }, schedule_update_scores.delays[submission_id]); |
91 | 134 | }; |
92 | 135 |
|
93 | 136 | $(document).ready(function () { |
94 | 137 | $('#submission_list tbody tr[data-status][data-status!="{{ SubmissionResult.COMPILATION_FAILED }}"][data-status!="{{ SubmissionResult.SCORED }}"]').each(function (idx, elem) { |
95 | | - schedule_update_submission_row($(this).attr("data-submission")); |
| 138 | + schedule_update_scores($(this).attr("data-submission")); |
96 | 139 | }); |
97 | 140 | }); |
98 | 141 |
|
|
106 | 149 | <h1>{% trans name=task.title, short_name=task.name %}{{ name }} ({{ short_name }}) <small>submissions</small>{% endtrans %}</h1> |
107 | 150 | </div> |
108 | 151 |
|
| 152 | +{% if score_type is defined %} |
| 153 | + {% set two_task_scores = score_type.max_public_score > 0 |
| 154 | + and score_type.max_public_score < score_type.max_score %} |
| 155 | +<div class="task_score_container row-fluid"> |
| 156 | + |
| 157 | + {% if score_type.max_public_score > 0 %} |
| 158 | + {# Show the public score (alone, if everything is public or tokens are disabled, or together with the tokened score). #} |
| 159 | + <div id="task_score_public" |
| 160 | + class="{{ "span6" if two_task_scores else "span12" }} well well-small task_score {{ get_score_class(public_score, score_type.max_public_score) }}"> |
| 161 | + <span> |
| 162 | + {% if score_type.max_public_score == score_type.max_score %} |
| 163 | + {% trans %}Score:{% endtrans %} |
| 164 | + {% else %} |
| 165 | + {% trans %}Public score:{% endtrans %} |
| 166 | + {% endif %} |
| 167 | + </span> |
| 168 | + <br/> |
| 169 | + <span class="score"> |
| 170 | + {{ score_type.format_score(public_score, score_type.max_public_score, none, task.score_precision, translation=translation) }} |
| 171 | + {% if is_score_partial %} |
| 172 | + <img src="{{ url("static", "loading.gif") }}" /> |
| 173 | + {% endif %} |
| 174 | + </span> |
| 175 | + </div> |
| 176 | + {% endif %} |
| 177 | + |
| 178 | + {% if score_type.max_public_score < score_type.max_score %} |
| 179 | + {# Show the tokened score (alone if everything is non-public, or together with the public score). #} |
| 180 | + <div id="task_score_tokened" |
| 181 | + class="{{ "span6" if two_task_scores else "span12" }} well well-small task_score {{ get_score_class(tokened_score, score_type.max_score) if can_use_tokens else "undefined" }}"> |
| 182 | + <span> |
| 183 | + {% if can_use_tokens %} |
| 184 | + {% trans %}Score of tokened submissions:{% endtrans %} |
| 185 | + {% else %} |
| 186 | + {% trans %}Total score:{% endtrans %} |
| 187 | + {% endif %} |
| 188 | + </span> |
| 189 | + <br/> |
| 190 | + <span class="score"> |
| 191 | + {% if can_use_tokens %} |
| 192 | + {{ score_type.format_score(tokened_score, score_type.max_score, none, task.score_precision, translation=translation) }} |
| 193 | + {% if is_score_partial %} |
| 194 | + <img src="{{ url("static", "loading.gif") }}" /> |
| 195 | + {% endif %} |
| 196 | + {% else %} |
| 197 | + {% trans %}N/A{% endtrans %} |
| 198 | + {% endif %} |
| 199 | + </span> |
| 200 | + </div> |
| 201 | + {% endif %} |
| 202 | + |
| 203 | +</div> |
| 204 | +{% endif %} |
109 | 205 |
|
110 | 206 | <h2 style="margin-bottom: 10px">{% trans %}Submit a solution{% endtrans %}</h2> |
111 | 207 |
|
@@ -229,8 +325,6 @@ <h2 style="margin: 40px 0 10px">{% trans %}Previous submissions{% endtrans %}</h |
229 | 325 | {% endif %} |
230 | 326 |
|
231 | 327 |
|
232 | | -{% set score_type = get_score_type(dataset=task.active_dataset) %} |
233 | | - |
234 | 328 | {% set show_date = not submissions|map(attribute="timestamp")|all("today") %} |
235 | 329 |
|
236 | 330 |
|
|
0 commit comments