Skip to content

Commit 8a551b6

Browse files
committed
Show if someone has multiple proposal in recap
1 parent ed679d2 commit 8a551b6

3 files changed

Lines changed: 71 additions & 0 deletions

File tree

backend/reviews/adapters.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,10 +177,21 @@ def get_recap_context(
177177
)
178178
}
179179

180+
# Count submissions per speaker for the current conference
181+
speaker_submission_counts = {
182+
str(speaker_id): count
183+
for speaker_id, count in Submission.objects.for_conference(conference.id)
184+
.non_cancelled()
185+
.values("speaker_id")
186+
.annotate(count=Count("id"))
187+
.values_list("speaker_id", "count")
188+
}
189+
180190
return dict(
181191
admin_site.each_context(request),
182192
items=items,
183193
grants=grants,
194+
speaker_submission_counts=speaker_submission_counts,
184195
review_session_id=review_session.id,
185196
audience_levels=conference.audience_levels.all(),
186197
submission_types=conference.submission_types.all(),

backend/reviews/templates/proposals-recap.html

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,18 @@
285285
tr:nth-of-type(odd) {
286286
background-color: var(--body-bg);
287287
}
288+
289+
.speaker-multi-submission-badge {
290+
display: inline-block;
291+
background-color: #f0ad4e;
292+
color: #fff;
293+
font-size: 10px;
294+
font-weight: bold;
295+
padding: 2px 6px;
296+
border-radius: 10px;
297+
margin-left: 6px;
298+
vertical-align: middle;
299+
}
288300
</style>
289301

290302
<script type="application/javascript">
@@ -650,6 +662,7 @@ <h3>Show proposals of type:</h3>
650662
</thead>
651663
<tbody>
652664
{% for item in items %}
665+
{% with speaker_id=item.speaker_id|stringformat:"i" %}
653666
<script>
654667
submissionsById[{{ item.id }}] = {
655668
id: {{ item.id }},
@@ -661,8 +674,10 @@ <h3>Show proposals of type:</h3>
661674
submissionType: "{{ item.type.name }}",
662675
speakerName: "{{ item.speaker.fullname|escapejs }}",
663676
speakerGender: "{{ item.speaker.gender|default:'unknown' }}",
677+
speakerSubmissionCount: {{ speaker_submission_counts|get_item:speaker_id|default:1 }},
664678
};
665679
</script>
680+
{% endwith %}
666681
<tr class="proposal-item" id="submission-{{item.id}}" data-original-status="{{ item.current_or_pending_status }}">
667682
<td>{{forloop.counter}}</td>
668683
<td class="results-title">
@@ -676,6 +691,11 @@ <h3>Show proposals of type:</h3>
676691
<li>
677692
<strong>Speaker</strong>
678693
<span class="speaker-name-link" onclick="filterBySpeakerName('{{ item.speaker.fullname|escapejs }}')">{{ item.speaker.fullname }}</span>
694+
{% with submission_count=speaker_submission_counts|get_item:speaker_id %}
695+
{% if submission_count and submission_count > 1 %}
696+
<span class="speaker-multi-submission-badge" title="This speaker has {{ submission_count }} submissions">{{ submission_count }} talks</span>
697+
{% endif %}
698+
{% endwith %}
679699
<button type="button" class="clear-filter-btn speaker-row-clear-btn" onclick="event.stopPropagation(); clearSpeakerFilter();" style="display: none;">Clear filter</button>
680700
</li>
681701
<li>

backend/reviews/tests/test_admin.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -833,8 +833,48 @@ def test_proposals_review_get_recap_context(rf):
833833
assert "review_session_id" in context
834834
assert "audience_levels" in context
835835
assert "all_statuses" in context
836+
assert "speaker_submission_counts" in context
836837
assert context["review_session_id"] == review_session.id
837838
assert str(submission.speaker_id) in context["grants"]
839+
# Verify speaker submission count is tracked
840+
assert str(submission.speaker_id) in context["speaker_submission_counts"]
841+
assert context["speaker_submission_counts"][str(submission.speaker_id)] == 1
842+
843+
844+
def test_proposals_review_get_recap_context_with_multiple_submissions_per_speaker(rf):
845+
user = UserFactory(is_staff=True, is_superuser=True)
846+
conference = ConferenceFactory()
847+
848+
review_session = ReviewSessionFactory(
849+
conference=conference,
850+
session_type=ReviewSession.SessionType.PROPOSALS,
851+
status=ReviewSession.Status.COMPLETED,
852+
)
853+
AvailableScoreOptionFactory(review_session=review_session, numeric_value=0)
854+
AvailableScoreOptionFactory(review_session=review_session, numeric_value=1)
855+
856+
# Create a speaker with multiple submissions
857+
speaker = UserFactory()
858+
submission_1 = SubmissionFactory(conference=conference, speaker=speaker)
859+
submission_2 = SubmissionFactory(conference=conference, speaker=speaker)
860+
submission_3 = SubmissionFactory(conference=conference, speaker=speaker)
861+
862+
# Create another speaker with only one submission
863+
single_speaker = UserFactory()
864+
single_submission = SubmissionFactory(conference=conference, speaker=single_speaker)
865+
866+
request = rf.get("/")
867+
request.user = user
868+
869+
adapter = get_review_adapter(review_session)
870+
items = adapter.get_recap_items_queryset(review_session).all()
871+
context = adapter.get_recap_context(request, review_session, items, AdminSite())
872+
873+
assert "speaker_submission_counts" in context
874+
# Speaker with 3 submissions should have count of 3
875+
assert context["speaker_submission_counts"][str(speaker.id)] == 3
876+
# Speaker with 1 submission should have count of 1
877+
assert context["speaker_submission_counts"][str(single_speaker.id)] == 1
838878

839879

840880
def test_proposals_review_process_recap_post(rf):

0 commit comments

Comments
 (0)