Skip to content

Commit 6f11e28

Browse files
committed
Add sorting functionality to grants recap
1 parent 3aa8daf commit 6f11e28

1 file changed

Lines changed: 92 additions & 2 deletions

File tree

backend/reviews/templates/grants-recap.html

Lines changed: 92 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,16 @@
224224
visibility: visible;
225225
opacity: 1;
226226
}
227+
228+
/* Sortable columns */
229+
.sortable {
230+
cursor: pointer;
231+
user-select: none;
232+
}
233+
234+
.sortable:hover {
235+
text-decoration: underline;
236+
}
227237
</style>
228238
<script type="application/javascript">
229239
const grantsById = {};
@@ -415,6 +425,84 @@
415425
{% endfor %}
416426

417427
};
428+
429+
// Sorting functionality
430+
const sortTable = (sortBy, direction) => {
431+
const tbody = document.querySelector('#result_list tbody');
432+
const rows = Array.from(tbody.querySelectorAll('tr.grant-item'));
433+
434+
rows.sort((a, b) => {
435+
let aVal, bVal;
436+
437+
if (sortBy === 'score') {
438+
aVal = parseFloat(a.dataset.score);
439+
bVal = parseFloat(b.dataset.score);
440+
} else if (sortBy === 'std_dev') {
441+
aVal = parseFloat(a.dataset.stdDev);
442+
bVal = parseFloat(b.dataset.stdDev);
443+
}
444+
445+
// Handle null/NaN values - push them to the end
446+
if (isNaN(aVal)) aVal = direction === 'desc' ? -Infinity : Infinity;
447+
if (isNaN(bVal)) bVal = direction === 'desc' ? -Infinity : Infinity;
448+
449+
if (direction === 'desc') {
450+
return bVal - aVal;
451+
} else {
452+
return aVal - bVal;
453+
}
454+
});
455+
456+
// Re-append rows in sorted order and update row numbers
457+
rows.forEach((row, index) => {
458+
row.querySelector('td:first-child').textContent = index + 1;
459+
tbody.appendChild(row);
460+
});
461+
};
462+
463+
const initSorting = () => {
464+
document.querySelectorAll('.sortable').forEach(header => {
465+
header.addEventListener('click', (e) => {
466+
e.stopPropagation();
467+
const sortBy = header.dataset.sort;
468+
let currentDir = header.dataset.sortDir;
469+
470+
// Toggle direction
471+
let newDir;
472+
if (currentDir === 'desc') {
473+
newDir = 'asc';
474+
} else {
475+
newDir = 'desc';
476+
}
477+
478+
// Update all sortable headers
479+
document.querySelectorAll('.sortable').forEach(h => {
480+
h.dataset.sortDir = '';
481+
// Remove arrow from text, keeping tooltip if present
482+
const tooltipSpan = h.querySelector('.tooltiptext');
483+
if (tooltipSpan) {
484+
h.childNodes[0].textContent = h.childNodes[0].textContent.replace(/ []/, '');
485+
} else {
486+
h.textContent = h.textContent.replace(/ []/, '');
487+
}
488+
});
489+
490+
// Set new direction and arrow
491+
header.dataset.sortDir = newDir;
492+
const arrow = newDir === 'desc' ? ' ▼' : ' ▲';
493+
const tooltipSpan = header.querySelector('.tooltiptext');
494+
if (tooltipSpan) {
495+
header.childNodes[0].textContent = header.childNodes[0].textContent.trim() + arrow;
496+
} else {
497+
header.textContent = header.textContent.trim() + arrow;
498+
}
499+
500+
sortTable(sortBy, newDir);
501+
});
502+
});
503+
};
504+
505+
window.addEventListener('load', initSorting);
418506
</script>
419507
<ul class="object-tools">
420508
<li>
@@ -471,13 +559,13 @@ <h3>
471559
</th>
472560
<th scope="col">
473561
<div class="text">
474-
<a>Score</a>
562+
<span class="sortable" data-sort="score" data-sort-dir="desc">Score</span>
475563
</div>
476564
<div class="clear"></div>
477565
</th>
478566
<th scope="col">
479567
<div class="text">
480-
<span class="tooltip">Std Dev
568+
<span class="tooltip sortable" data-sort="std_dev" data-sort-dir="">Std Dev
481569
<span class="tooltiptext">Standard Deviation: measures reviewer disagreement. High value = controversial (needs discussion), Low value = consensus.</span>
482570
</span>
483571
</div>
@@ -532,6 +620,8 @@ <h3>
532620
id="grant-{{ item.id }}"
533621
data-type="{{ item.type }}"
534622
data-num-of-votes="{{ item.userreview_set.count }}"
623+
data-score="{{ item.score|default_if_none:'-999' }}"
624+
data-std-dev="{{ item.std_dev|default_if_none:'-1' }}"
535625
>
536626
<td>{{ forloop.counter }}</td>
537627
<td class="results-item">

0 commit comments

Comments
 (0)