From 9dcd8312711ec5542ab1050f486a4a58b0f3eaa2 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <41898282+claude[bot]@users.noreply.github.com> Date: Fri, 30 Jan 2026 15:54:27 +0000 Subject: [PATCH 1/2] Add submission type filter to proposal review recap screen Allow filtering proposals by type (e.g. talk, workshop) in the recap screen using checkboxes, similar to the existing status filter. Also refactors the filtering logic to apply all filters (reviews count, status, and type) together rather than independently, preventing filters from overriding each other. Closes #4537 Co-authored-by: Marco Acierno --- backend/reviews/adapters.py | 1 + .../reviews/templates/proposals-recap.html | 88 ++++++++----------- 2 files changed, 38 insertions(+), 51 deletions(-) diff --git a/backend/reviews/adapters.py b/backend/reviews/adapters.py index e40e883bb1..06b1b64787 100644 --- a/backend/reviews/adapters.py +++ b/backend/reviews/adapters.py @@ -183,6 +183,7 @@ def get_recap_context( grants=grants, review_session_id=review_session.id, audience_levels=conference.audience_levels.all(), + submission_types=conference.submission_types.all(), review_session_repr=str(review_session), all_statuses=[choice for choice in Submission.STATUS], title="Recap", diff --git a/backend/reviews/templates/proposals-recap.html b/backend/reviews/templates/proposals-recap.html index 02ef5d5d5c..15e9817527 100644 --- a/backend/reviews/templates/proposals-recap.html +++ b/backend/reviews/templates/proposals-recap.html @@ -259,59 +259,33 @@ }); const filterWithReviewsSelect = document.querySelector('#filter-with-n-reviews'); - filterWithReviewsSelect.addEventListener('change', e => { - e.preventDefault(); - - const filterValue = parseInt(e.target.value, 10); - - document.querySelectorAll('.proposal-item').forEach( - proposalRow => { - if (e.target.value === 'all') { - proposalRow.classList.remove('hidden') - return; - } - - const proposalId = parseInt(proposalRow.id.split('-')[1], 10); - const proposalData = submissionsById[proposalId]; - - const numOfVotes = proposalData.numOfVotes; - if (numOfVotes === filterValue) { - proposalRow.classList.remove('hidden') - } else { - proposalRow.classList.add('hidden') - } + const filterByStatusInputs = [...document.querySelectorAll('input[name="filter-by-status"]')]; + const filterByTypeInputs = [...document.querySelectorAll('input[name="filter-by-type"]')]; + + const applyFilters = () => { + const reviewFilterValue = filterWithReviewsSelect.value; + const visibleStatuses = filterByStatusInputs.filter(input => input.checked).map(input => input.value); + const visibleTypes = filterByTypeInputs.filter(input => input.checked).map(input => input.value); + + document.querySelectorAll('.proposal-item').forEach(proposalRow => { + const proposalId = parseInt(proposalRow.id.split('-')[1], 10); + const proposalData = submissionsById[proposalId]; + + const matchesReviews = reviewFilterValue === 'all' || proposalData.numOfVotes === parseInt(reviewFilterValue, 10); + const matchesStatus = visibleStatuses.includes(proposalData.originalStatus); + const matchesType = visibleTypes.includes(proposalData.submissionType); + + if (matchesReviews && matchesStatus && matchesType) { + proposalRow.classList.remove('hidden'); + } else { + proposalRow.classList.add('hidden'); } - ) - }); + }); + }; - const filterByStatusInputs = [...document.querySelectorAll('input[name="filter-by-status"]')]; - filterByStatusInputs.forEach( - filterByStatusInput => { - filterByStatusInput.addEventListener('change', e => { - e.preventDefault(); - - const filterValue = e.target.value; - const visibleStatuses = filterByStatusInputs.filter( - input => input.checked - ).map( - input => input.value - ); - - document.querySelectorAll('.proposal-item').forEach( - proposalRow => { - const proposalId = parseInt(proposalRow.id.split('-')[1], 10); - const proposalData = submissionsById[proposalId]; - - if (visibleStatuses.includes(proposalData.originalStatus)) { - proposalRow.classList.remove('hidden') - } else { - proposalRow.classList.add('hidden') - } - } - ); - }); - } - ); + filterWithReviewsSelect.addEventListener('change', applyFilters); + filterByStatusInputs.forEach(input => input.addEventListener('change', applyFilters)); + filterByTypeInputs.forEach(input => input.addEventListener('change', applyFilters)); }); const updateBottomBarUI = () => { @@ -431,6 +405,17 @@

Show proposals with pending status:

{% endfor %} +
+

Show proposals with type:

+
+ {% for submission_type in submission_types %} + + {% endfor %} +
+
@@ -478,6 +463,7 @@

Show proposals with pending status:

audienceLevel: {{ item.audience_level.id }}, languages: [{% for language in item.languages.all %}"{{language.code}}",{% endfor %}], numOfVotes: {{item.userreview_set.count}}, + submissionType: "{{ item.type.name }}", }; From 980ab9be27da722d2ecade9c0015e4decc0b7308 Mon Sep 17 00:00:00 2001 From: Marco Acierno Date: Fri, 30 Jan 2026 16:57:30 +0100 Subject: [PATCH 2/2] of type --- backend/reviews/templates/proposals-recap.html | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/backend/reviews/templates/proposals-recap.html b/backend/reviews/templates/proposals-recap.html index 15e9817527..4ad965f72a 100644 --- a/backend/reviews/templates/proposals-recap.html +++ b/backend/reviews/templates/proposals-recap.html @@ -197,7 +197,7 @@ const bottomBar = document.querySelector('.reviews-bottom-bar'); const toggleIcon = document.getElementById('toggle-icon'); const toggleButton = document.getElementById('bottom-bar-toggle'); - + if (bottomBar && toggleIcon && toggleButton) { if (bottomBarHidden) { bottomBar.classList.add('hidden'); @@ -206,7 +206,7 @@ } else { toggleButton.setAttribute('aria-expanded', 'true'); } - + toggleButton.addEventListener('click', toggleBottomBar); } @@ -358,14 +358,14 @@ const bottomBar = document.querySelector('.reviews-bottom-bar'); const toggleIcon = document.getElementById('toggle-icon'); const toggleButton = document.getElementById('bottom-bar-toggle'); - + if (!bottomBar || !toggleIcon || !toggleButton) { console.warn('Required elements for bottom bar toggle not found'); return; } - + bottomBar.classList.toggle('hidden'); - + if (bottomBar.classList.contains('hidden')) { toggleIcon.textContent = '▲'; toggleButton.setAttribute('aria-expanded', 'false'); @@ -373,7 +373,7 @@ toggleIcon.textContent = '▼'; toggleButton.setAttribute('aria-expanded', 'true'); } - + // Save preference in localStorage localStorage.setItem('proposalsBottomBarHidden', bottomBar.classList.contains('hidden')); }; @@ -406,7 +406,7 @@

Show proposals with pending status:

-

Show proposals with type:

+

Show proposals of type:

{% for submission_type in submission_types %}