Skip to content

Commit 9dcd831

Browse files
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 <marcoacierno@users.noreply.github.com>
1 parent aa24626 commit 9dcd831

2 files changed

Lines changed: 38 additions & 51 deletions

File tree

backend/reviews/adapters.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ def get_recap_context(
183183
grants=grants,
184184
review_session_id=review_session.id,
185185
audience_levels=conference.audience_levels.all(),
186+
submission_types=conference.submission_types.all(),
186187
review_session_repr=str(review_session),
187188
all_statuses=[choice for choice in Submission.STATUS],
188189
title="Recap",

backend/reviews/templates/proposals-recap.html

Lines changed: 37 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -259,59 +259,33 @@
259259
});
260260

261261
const filterWithReviewsSelect = document.querySelector('#filter-with-n-reviews');
262-
filterWithReviewsSelect.addEventListener('change', e => {
263-
e.preventDefault();
264-
265-
const filterValue = parseInt(e.target.value, 10);
266-
267-
document.querySelectorAll('.proposal-item').forEach(
268-
proposalRow => {
269-
if (e.target.value === 'all') {
270-
proposalRow.classList.remove('hidden')
271-
return;
272-
}
273-
274-
const proposalId = parseInt(proposalRow.id.split('-')[1], 10);
275-
const proposalData = submissionsById[proposalId];
276-
277-
const numOfVotes = proposalData.numOfVotes;
278-
if (numOfVotes === filterValue) {
279-
proposalRow.classList.remove('hidden')
280-
} else {
281-
proposalRow.classList.add('hidden')
282-
}
262+
const filterByStatusInputs = [...document.querySelectorAll('input[name="filter-by-status"]')];
263+
const filterByTypeInputs = [...document.querySelectorAll('input[name="filter-by-type"]')];
264+
265+
const applyFilters = () => {
266+
const reviewFilterValue = filterWithReviewsSelect.value;
267+
const visibleStatuses = filterByStatusInputs.filter(input => input.checked).map(input => input.value);
268+
const visibleTypes = filterByTypeInputs.filter(input => input.checked).map(input => input.value);
269+
270+
document.querySelectorAll('.proposal-item').forEach(proposalRow => {
271+
const proposalId = parseInt(proposalRow.id.split('-')[1], 10);
272+
const proposalData = submissionsById[proposalId];
273+
274+
const matchesReviews = reviewFilterValue === 'all' || proposalData.numOfVotes === parseInt(reviewFilterValue, 10);
275+
const matchesStatus = visibleStatuses.includes(proposalData.originalStatus);
276+
const matchesType = visibleTypes.includes(proposalData.submissionType);
277+
278+
if (matchesReviews && matchesStatus && matchesType) {
279+
proposalRow.classList.remove('hidden');
280+
} else {
281+
proposalRow.classList.add('hidden');
283282
}
284-
)
285-
});
283+
});
284+
};
286285

287-
const filterByStatusInputs = [...document.querySelectorAll('input[name="filter-by-status"]')];
288-
filterByStatusInputs.forEach(
289-
filterByStatusInput => {
290-
filterByStatusInput.addEventListener('change', e => {
291-
e.preventDefault();
292-
293-
const filterValue = e.target.value;
294-
const visibleStatuses = filterByStatusInputs.filter(
295-
input => input.checked
296-
).map(
297-
input => input.value
298-
);
299-
300-
document.querySelectorAll('.proposal-item').forEach(
301-
proposalRow => {
302-
const proposalId = parseInt(proposalRow.id.split('-')[1], 10);
303-
const proposalData = submissionsById[proposalId];
304-
305-
if (visibleStatuses.includes(proposalData.originalStatus)) {
306-
proposalRow.classList.remove('hidden')
307-
} else {
308-
proposalRow.classList.add('hidden')
309-
}
310-
}
311-
);
312-
});
313-
}
314-
);
286+
filterWithReviewsSelect.addEventListener('change', applyFilters);
287+
filterByStatusInputs.forEach(input => input.addEventListener('change', applyFilters));
288+
filterByTypeInputs.forEach(input => input.addEventListener('change', applyFilters));
315289
});
316290

317291
const updateBottomBarUI = () => {
@@ -431,6 +405,17 @@ <h3>Show proposals with pending status:</h3>
431405
{% endfor %}
432406
</div>
433407
</div>
408+
<div class="opt-filter">
409+
<h3>Show proposals with type:</h3>
410+
<div>
411+
{% for submission_type in submission_types %}
412+
<label>
413+
<input checked type="checkbox" name="filter-by-type" value="{{ submission_type.name }}">
414+
<span>{{ submission_type.name }}</span>
415+
</label>
416+
{% endfor %}
417+
</div>
418+
</div>
434419
</div>
435420
<div class="module filtered" id="changelist">
436421
<div class="changelist-form-container">
@@ -478,6 +463,7 @@ <h3>Show proposals with pending status:</h3>
478463
audienceLevel: {{ item.audience_level.id }},
479464
languages: [{% for language in item.languages.all %}"{{language.code}}",{% endfor %}],
480465
numOfVotes: {{item.userreview_set.count}},
466+
submissionType: "{{ item.type.name }}",
481467
};
482468
</script>
483469
<tr class="proposal-item" id="submission-{{item.id}}" data-original-status="{{ item.current_or_pending_status }}">

0 commit comments

Comments
 (0)