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

Show list of submissions on public and team scoreboards when clicking on a cell #2918

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Open
8 changes: 8 additions & 0 deletions webapp/public/style_domjudge.css
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,14 @@ tr.ignore td, td.ignore, span.ignore {
min-width: 2em;
}

h5 .problem-badge {
font-size: 1rem;
}

h1 .problem-badge {
font-size: 2rem;
}

.tooltip .tooltip-inner {
max-width: 500px;
}
Expand Down
64 changes: 64 additions & 0 deletions webapp/src/Controller/PublicController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace App\Controller;

use App\DataTransferObject\SubmissionRestriction;
use App\Entity\Contest;
use App\Entity\ContestProblem;
use App\Entity\Team;
Expand All @@ -11,6 +12,7 @@
use App\Service\EventLogService;
use App\Service\ScoreboardService;
use App\Service\StatisticsService;
use App\Service\SubmissionService;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\NonUniqueResultException;
use Symfony\Component\HttpFoundation\RedirectResponse;
Expand All @@ -33,6 +35,7 @@ public function __construct(
protected readonly ConfigurationService $config,
protected readonly ScoreboardService $scoreboardService,
protected readonly StatisticsService $stats,
protected readonly SubmissionService $submissionService,
EntityManagerInterface $em,
EventLogService $eventLog,
KernelInterface $kernel,
Expand Down Expand Up @@ -79,6 +82,18 @@ public function scoreboardAction(

if ($static) {
$data['hide_menu'] = true;
$submissions = $this->submissionService->getSubmissionList(
[$contest->getCid() => $contest],
new SubmissionRestriction(valid: true),
paginated: false
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For long running contests we would still get a long list?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For one team? We would if the team submits a lot. We can add this behind an option if this becomes a problem.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is the modal scrollable?

)[0];

$submissionsPerTeamAndProblem = [];
foreach ($submissions as $submission) {
$submissionsPerTeamAndProblem[$submission->getTeam()->getTeamid()][$submission->getProblem()->getProbid()][] = $submission;
}
$data['submissionsPerTeamAndProblem'] = $submissionsPerTeamAndProblem;
$data['verificationRequired'] = $this->config->get('verification_required');
}

$data['current_contest'] = $contest;
Expand Down Expand Up @@ -267,4 +282,53 @@ protected function getBinaryFile(int $probId, callable $response): StreamedRespo

return $response($probId, $contest, $contestProblem);
}

#[Route(path: '/submissions/team/{teamId<\d+>}/problem/{problemId<\d+>}', name: 'public_submissions')]
public function submissionsAction(Request $request, int $teamId, int $problemId): Response
{
$contest = $this->dj->getCurrentContest(onlyPublic: true);

if (!$contest) {
throw $this->createNotFoundException('No active contest found');
}

/** @var Team|null $team */
$team = $this->em->getRepository(Team::class)->find($teamId);
if ($team && $team->getCategory() && !$team->getCategory()->getVisible()) {
$team = null;
}

if (!$team) {
throw $this->createNotFoundException('Team not found.');
}

/** @var ContestProblem|null $problem */
$problem = $this->em->getRepository(ContestProblem::class)->find([
'problem' => $problemId,
'contest' => $contest,
]);

if (!$problem) {
throw $this->createNotFoundException('Problem not found');
}

$submissions = $this->submissionService->getSubmissionList(
[$contest->getCid() => $contest],
new SubmissionRestriction(teamId: $teamId, problemId: $problemId, valid: true),
paginated: false
)[0];

$data = [
'contest' => $contest,
'problem' => $problem,
'team' => $team,
'submissions' => $submissions,
'verificationRequired' => $this->config->get('verification_required'),
];

if ($request->isXmlHttpRequest()) {
return $this->render('public/team_submissions_modal.html.twig', $data);
}
return $this->render('public/team_submissions.html.twig', $data);
}
}
1 change: 1 addition & 0 deletions webapp/src/DataTransferObject/SubmissionRestriction.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,5 +69,6 @@ public function __construct(
public ?bool $externallyJudged = null,
public ?bool $externallyVerified = null,
public ?bool $withExternalId = null,
public ?bool $valid = null,
) {}
}
6 changes: 6 additions & 0 deletions webapp/src/Service/SubmissionService.php
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,12 @@ public function getSubmissionList(
->setParameter('results', $restrictions->results);
}

if (isset($restrictions->valid)) {
$queryBuilder
->andWhere('s.valid = :valid')
->setParameter('valid', $restrictions->valid);
}

if ($this->dj->shadowMode()) {
// When we are shadow, also load the external results
$queryBuilder
Expand Down
11 changes: 9 additions & 2 deletions webapp/src/Twig/TwigExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -513,8 +513,12 @@ public function displayTestcaseResults(array $testcases, bool $submissionDone, b
return $results;
}

public function printResult(?string $result, bool $valid = true, bool $jury = false): string
{
public function printResult(
?string $result,
bool $valid = true,
bool $jury = false,
bool $onlyRejectedForIncorrect = false,
): string {
$result = strtolower($result ?? '');
switch ($result) {
case 'too-late':
Expand All @@ -539,6 +543,9 @@ public function printResult(?string $result, bool $valid = true, bool $jury = fa
break;
default:
$style = 'sol_incorrect';
if ($onlyRejectedForIncorrect) {
$result = 'rejected';
}
}

return sprintf('<span class="sol %s">%s</span>', $valid ? $style : 'disabled', $result);
Expand Down
20 changes: 18 additions & 2 deletions webapp/templates/partials/scoreboard_table.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -286,15 +286,21 @@
{% endif %}
{% endif %}

{% set link = null %}
{% set extra = null %}
{% if jury %}
{% set restrict = {problemId: problem.probid} %}
{% set link = path('jury_team', {teamId: score.team.teamid, restrict: restrict}) %}
{% elseif static %}
{% set link = '#' %}
{% set extra = 'data-bs-toggle="modal" data-bs-target="#team-submissions-modal-' ~ score.team.teamid ~ '-' ~ problem.probid ~ '"' %}
{% else %}
{% set link = path('public_submissions', {teamId: score.team.teamid, problemId: problem.probid}) %}
{% set extra = 'data-ajax-modal' %}
{% endif %}

<td class="score_cell">
{% if numSubmissions != '0' %}
<a {% if link %}href="{{ link }}"{% endif %}>
<a {% if link %}href="{{ link }}"{% endif %} {% if extra %}{{ extra | raw }}{% endif %}>
<div class="{{ scoreCssClass }}">
{% if matrixItem.isCorrect %}{{ time }}{% else %}&nbsp;{% endif %}
<span>
Expand Down Expand Up @@ -503,6 +509,16 @@
{% include 'partials/team.html.twig' with {size: 6, team: score.team} %}
{% endblock %}
{% endembed %}
{% for problem in problems %}
{% embed 'partials/modal.html.twig' with {'modalId': 'team-submissions-modal-' ~ score.team.teamid ~ '-' ~ problem.probid} %}
{% block title %}
Submissions for team {{ score.team.effectiveName }} on problem {{ problem | problemBadge }} {{ problem.problem.name }}
{% endblock %}
{% block content %}
{% include 'public/partials/submission_list.html.twig' with {size: 6, team: score.team, submissions: submissionsPerTeamAndProblem[score.team.teamid][problem.probid] ?? []} %}
{% endblock %}
{% endembed %}
{% endfor %}
{% endfor %}
{% endif %}

Expand Down
43 changes: 43 additions & 0 deletions webapp/templates/public/partials/submission_list.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{# Render a list of submissions for the scoreboard #}
{# @var submission \App\Entity\Submission #}

{% if submissions is empty %}
<div class="alert alert-warning">No submissions</div>
{% else %}
<table class="data-table table table-hover table-striped table-sm submissions-table">
<thead class="thead-light">
<tr>
<th scope="col">time</th>
<th scope="col">language</th>
<th scope="col">result</th>
</tr>
</thead>
<tbody>
{% for submission in submissions %}
<tr>
<td>
{{ submission.submittime | printtime(null, submission.contest) }}
</td>
<td class="langid">
{{ submission.language.langid }}
</td>
<td>
{% if submission.submittime >= submission.contest.endtime %}
{{ 'too-late' | printResult }}
{% elseif submission.contest.freezetime and submission.submittime >= submission.contest.freezetime and not contest.freezeData.showFinal %}
{{ '' | printResult }}
{% else %}
{% if submission.judgings.first is empty or submission.judgings.first.result is empty %}
{{ '' | printResult }}
{% elseif verificationRequired and not submission.judgings.first.verified %}
{{ '' | printResult }}
{% else %}
{{ submission.judgings.first.result | printResult(true, false, true) }}
{% endif %}
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
13 changes: 13 additions & 0 deletions webapp/templates/public/team_submissions.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{% extends "public/base.html.twig" %}

{% block title %}
{% if team is not empty %}Submissions for team {{ team.effectiveName }} on problem {{ problem.problem.name }} - {% endif %}{{ parent() }}
{% endblock %}

{% block content %}
<h1 class="mt-3">
Submissions for team {{ team.effectiveName }} on problem {{ problem | problemBadge }} {{ problem.problem.name }}
</h1>

{% include 'public/partials/submission_list.html.twig' %}
{% endblock %}
9 changes: 9 additions & 0 deletions webapp/templates/public/team_submissions_modal.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{% extends "partials/modal.html.twig" %}

{% block title %}
Submissions for team {{ team.effectiveName }} on problem {{ problem | problemBadge }} {{ problem.problem.name }}
{% endblock %}

{% block content %}
{% include 'public/partials/submission_list.html.twig' %}
{% endblock %}
8 changes: 4 additions & 4 deletions webapp/templates/team/partials/submission_list.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@
</td>
<td>
<a data-ajax-modal data-ajax-modal-after="markSeen" {% if link %}href="{{ link }}"{% endif %}>
{%- if submission.submittime > submission.contest.endtime %}
{{ 'too-late' | printResult }}
{%- if submission.submittime >= submission.contest.endtime %}
{{ 'too-late' | printResult }}
{%- endif %}
{%- if submission.submittime <= submission.contest.endtime or showTooLateResult %}
{%- if submission.submittime > submission.contest.endtime %}
{%- if submission.submittime < submission.contest.endtime or showTooLateResult %}
{%- if submission.submittime >= submission.contest.endtime %}
/
{% endif %}
{%- if submission.judgings.first is empty or submission.judgings.first.result is empty %}
Expand Down
Loading