Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
55 changes: 55 additions & 0 deletions webapp/src/Controller/Team/ClarificationController.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,61 @@ public function __construct(
parent::__construct($em, $eventLogService, $dj, $kernel);
}

#[Route(path: '/clarifications/by-problem/{probId<\d+>}', name: 'team_clarification_by_prob')]
public function viewByProblemAction(Request $request, int $probId): Response
{
$user = $this->dj->getUser();
$team = $user->getTeam();
$teamId = $team->getTeamid();
$contest = $this->dj->getCurrentContest($teamId);

$problem = $this->em->getRepository(Problem::class)->find($probId);
if ($problem === null) {
throw new NotFoundHttpException(sprintf('Problem %d not found', $probId));
}
$contestProblem = $problem->getContestProblems();
$foundProblemInContest = false;
foreach ($contestProblem as $cp) {
if ($cp->getContest()->getCid() === $contest->getCid()) {
$foundProblemInContest = true;
break;
}
}
if (!$foundProblemInContest) {
throw new NotFoundHttpException(sprintf('Problem %d not in current contest', $probId));
}

/** @var Clarification[] $clarifications */
$clarifications = $this->em->createQueryBuilder()
->from(Clarification::class, 'c')
->leftJoin('c.problem', 'p')
->leftJoin('c.sender', 's')
->leftJoin('c.recipient', 'r')
->select('c', 'p')
->andWhere('c.contest = :contest')
->andWhere('c.sender IS NULL')
->andWhere('c.recipient = :team OR c.recipient IS NULL')
->andWhere('c.problem = :problem')
->setParameter('contest', $contest)
->setParameter('team', $team)
->setParameter('problem', $problem)
->addOrderBy('c.submittime', 'DESC')
->addOrderBy('c.clarid', 'DESC')
->getQuery()
->getResult();

$data = [
'clarifications' => $clarifications,
'team' => $team,
'problem' => $problem,
];
if ($request->isXmlHttpRequest()) {
return $this->render('team/clarifications_by_problem_modal.html.twig', $data);
} else {
return $this->render('team/clarifications_by_problem.html.twig', $data);
}
}

/**
* @throws NonUniqueResultException
*/
Expand Down
24 changes: 24 additions & 0 deletions webapp/src/Service/DOMJudgeService.php
Original file line number Diff line number Diff line change
Expand Up @@ -1028,6 +1028,7 @@ public function getTwigDataForProblemsAction(

$problems = [];
$samples = [];
$clars = [];
if ($contest && ($forJury || $contest->getFreezeData()->started())) {
$problems = $this->em->createQueryBuilder()
->from(ContestProblem::class, 'cp')
Expand Down Expand Up @@ -1057,6 +1058,27 @@ public function getTwigDataForProblemsAction(
foreach ($samplesData as $sample) {
$samples[$sample['probid']] = $sample['numsamples'];
}

$raw_clars = $this->em->createQueryBuilder()
->from(Clarification::class, 'clar')
->select('clar')
->andWhere('clar.contest = :cid')
// Only clars associated with a problem.
->andWhere('clar.problem IS NOT NULL')
// Only clars send from the jury.
->andWhere('clar.sender IS NULL')
// Only clars send to all teams or just this team.
->andWhere('clar.recipient IS NULL OR clar.recipient = :teamid')
->setParameter('cid', $contest->getCid())
->setParameter('teamid', $teamId)
->orderBy('clar.submittime', 'DESC')
->getQuery()
->getResult();

// Group clarifications by problem id.
foreach ($raw_clars as $clar) {
$clars[$clar->getProblem()->getProbid()][] = $clar;
}
}

$data = [
Expand All @@ -1065,6 +1087,8 @@ public function getTwigDataForProblemsAction(
'showLimits' => $showLimits,
'defaultMemoryLimit' => $defaultMemoryLimit,
'timeFactorDiffers' => $timeFactorDiffers,
'clarifications' => $clars,
'team' => $teamId ? $this->em->getRepository(Team::class)->find($teamId) : null,
];

if ($contest && $this->config->get('show_public_stats')) {
Expand Down
58 changes: 43 additions & 15 deletions webapp/templates/partials/problem_list.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -109,21 +109,6 @@
{% endif %}

<div class="text-center">
{% if problem.problem.problemstatementType is not empty %}
<a class="btn btn-secondary" role="button"
href="{{ path(problem_statement_path, {'probId': problem.probid}) }}">
<i class="fas fa-file-{{ problem.problem.problemstatementType }}"></i>
statement
</a>
{% endif %}

{% if numsamples > 0 %}
<a class="btn btn-secondary" role="button"
href="{{ path(problem_sample_zip_path, {'probId': problem.probid}) }}">
<i class="fas fa-file-archive"></i> samples
</a>
{% endif %}

{% if show_submit_button | default(false) %}
{% if is_granted('ROLE_JURY') or (current_team_contest is not null and current_team_contest.freezeData.started) %}
<a class="justify-content-center" data-ajax-modal data-ajax-modal-after="initSubmitModal" href="{{ path('team_submit', {problem: problem.probid}) }}">
Expand All @@ -139,6 +124,49 @@
</a>
{% endif %}
{% endif %}

{% set clarificationsCount = 0 %}
{% set unseenClarificationCount = 0 %}
{% if clarifications[problem.probid] is defined %}
{% set clarificationsCount = clarifications[problem.probid] | length %}
{% for clar in clarifications[problem.probid] %}
{% if team.unreadClarifications.contains(clar) %}
{% set unseenClarificationCount = unseenClarificationCount + 1 %}
{% endif %}
{% endfor %}
{% endif %}
{% if clarificationsCount > 0 %}
<a data-ajax-modal class="btn btn-secondary" role="button"
href="{{ path('team_clarification_by_prob', {'probId': problem.probid}) }}">
<i class="fas fa-question-circle"></i>
{% if clarificationsCount > 0 %}
{% set badgeClass = 'text-bg-info' %}
{% if unseenClarificationCount > 0 %}
{% set badgeClass = 'text-bg-danger' %}
{% endif %}
<span class="badge {{ badgeClass }}">{{ clarificationsCount }}</span>
{% endif %}
clarifications
</a>
{% endif %}

<div style="margin-top: 10px;">
</div>

{% if problem.problem.problemstatementType is not empty %}
<a class="btn btn-secondary" role="button"
href="{{ path(problem_statement_path, {'probId': problem.probid}) }}">
<i class="fas fa-file-{{ problem.problem.problemstatementType }}"></i>
statement
</a>
{% endif %}

{% if numsamples > 0 %}
<a class="btn btn-secondary" role="button"
href="{{ path(problem_sample_zip_path, {'probId': problem.probid}) }}">
<i class="fas fa-file-archive"></i> samples
</a>
{% endif %}
</div>

{% if problem.problem.attachments | length > 0 %}
Expand Down
33 changes: 33 additions & 0 deletions webapp/templates/team/clarifications_by_problem.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{% extends 'team/base.html.twig' %}

{% block title %}View clarifications for problem {{ problem.name }}{% endblock %}

{% block extrahead %}
{{ parent() }}
<style>
.data-table td a, .data-table td a:hover {
display: block;
text-decoration: none;
color: inherit;
padding: 3px 5px;
}

.data-table tr {
border-bottom: 1px solid silver;
}

.data-table tr:hover {
background: #ffffcc !important;
}
</style>
{% endblock %}

{% block content %}
<h2 class="text-center mt-4">Clarifications for {{ problem | problemBadgeForContest }} {{ problem.name }}</h2>

{% if clarifications is empty %}
<p class="nodata">No clarifications.</p>
{% else %}
{% include 'team/partials/clarification_list.html.twig' with {clarifications: clarifications} %}
{% endif %}
{% endblock %}
31 changes: 31 additions & 0 deletions webapp/templates/team/clarifications_by_problem_modal.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{% extends "partials/modal.html.twig" %}

{% block title %}View clarifications for problem {{ problem | problemBadgeForContest }} {{ problem.name }}{% endblock %}

{% block extrahead %}
{{ parent() }}
<style>
.data-table td a, .data-table td a:hover {
display: block;
text-decoration: none;
color: inherit;
padding: 3px 5px;
}

.data-table tr {
border-bottom: 1px solid silver;
}

.data-table tr:hover {
background: #ffffcc !important;
}
</style>
{% endblock %}

{% block content %}
{% if clarifications is empty %}
<p class="nodata">No clarifications.</p>
{% else %}
{% include 'team/partials/clarification_list.html.twig' with {clarifications: clarifications, subject: false} %}
{% endif %}
{% endblock %}
33 changes: 21 additions & 12 deletions webapp/templates/team/partials/clarification_list.html.twig
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
{% set includeSubject = true %}
{% if subject is defined and not subject %}
{% set includeSubject = false %}
{% endif %}

<div class="table-wrapper">
<table class="data-table table table-striped table-hover table-sm" style="width:100%;">
<thead class="thead-light">
<tr>
<th scope="col">time</th>
<th scope="col">from</th>
<th scope="col">to</th>
<th scope="col">subject</th>
{% if includeSubject %}
<th scope="col">subject</th>
{% endif %}
<th scope="col">text</th>
</tr>
</thead>
Expand Down Expand Up @@ -41,17 +48,19 @@
{{ recipient | u.truncate(teamname_max_length, '…') }}
</a>
</td>
<td>
<a data-ajax-modal data-ajax-modal-after="markSeen" href="{{ link }}">
{%- if clarification.problem -%}
problem {{ clarification.contestProblem | problemBadge -}}
{%- elseif clarification.category -%}
{{- categories[clarification.category]|default('general') -}}
{%- else -%}
general
{%- endif -%}
</a>
</td>
{% if includeSubject %}
<td>
<a data-ajax-modal data-ajax-modal-after="markSeen" href="{{ link }}">
{%- if clarification.problem -%}
problem {{ clarification.contestProblem | problemBadge -}}
{%- elseif clarification.category -%}
{{- categories[clarification.category]|default('general') -}}
{%- else -%}
general
{%- endif -%}
</a>
</td>
{% endif %}

<td>
<a data-ajax-modal data-ajax-modal-after="markSeen" href="{{ link }}">
Expand Down
3 changes: 2 additions & 1 deletion webapp/templates/team/problems.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
problem_statement_path: 'team_problem_statement',
problem_attachment_path: 'team_problem_attachment',
problem_sample_zip_path: 'team_problem_sample_zip',
show_submit_button: true
show_submit_button: true,
team: team
} %}
{% endblock %}
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ public function testSamples(): void
$cardBodies->eq(2)->filter('.list-group .list-group-item')->count());

// Check the link to download all samples.
$link = $cardBodies->eq(1)->filter('a')->eq(1);
$link = $cardBodies->eq(1)->filter('a')->eq(2);
self::assertSame('samples', $link->text(null, true));
self::assertSame(sprintf('/team/%d/samples.zip',
$problem->getProbid()),
Expand Down
Loading