diff --git a/client/db/set-list/index.html b/client/db/set-list/index.html
index b7009f877..ff52e3d27 100644
--- a/client/db/set-list/index.html
+++ b/client/db/set-list/index.html
@@ -18,12 +18,12 @@
- | Set Name |
- Difficulty |
- Standard |
- # of Packets |
- # of Tossups |
- # of Bonuses |
+ Set Name |
+ Difficulty |
+ Standard |
+ # of Packets |
+ # of Tossups |
+ # of Bonuses |
diff --git a/client/db/set-list/index.js b/client/db/set-list/index.js
index 1adb67261..2201d73c8 100644
--- a/client/db/set-list/index.js
+++ b/client/db/set-list/index.js
@@ -1,3 +1,11 @@
+import sortTable from '../../scripts/utilities/tables.js';
+
+const isNumericColumn = [false, true, false, true, true, true];
+
+document.querySelectorAll('th').forEach((th, index) => {
+ th.addEventListener('click', () => sortTable(index, isNumericColumn[index], 'set-metadata-list', 0, 0));
+});
+
await fetch('/api/db-explorer/set-metadata?' + new URLSearchParams({ includeCounts: false }))
.then(res => res.json())
.then(data => data.data)
@@ -6,6 +14,7 @@ await fetch('/api/db-explorer/set-metadata?' + new URLSearchParams({ includeCoun
const table = document.getElementById('set-metadata-list');
data.forEach(({ _id, setName, difficulty, standard }) => {
const row = table.insertRow(-1);
+ row.dataset.setId = _id;
const a = document.createElement('a');
a.href = `../set/?_id=${_id}`;
a.textContent = setName;
@@ -24,10 +33,14 @@ fetch('/api/db-explorer/set-metadata?' + new URLSearchParams({ includeCounts: tr
.then(data => {
document.getElementById('spinner').classList.add('d-none');
const table = document.getElementById('set-metadata-list');
- const rows = table.rows;
- for (let i = 0; i < data.length; i++) {
- rows[i].cells[3].textContent = data[i].packetsCount;
- rows[i].cells[4].textContent = data[i].tossupsCount;
- rows[i].cells[5].textContent = data[i].bonusesCount;
+ // Look rows up by set id instead of index: the user may have sorted the
+ // table while this request was in flight, which reorders the rows.
+ const rowsBySetId = new Map(Array.from(table.rows).map(row => [row.dataset.setId, row]));
+ for (const { _id, packetsCount, tossupsCount, bonusesCount } of data) {
+ const row = rowsBySetId.get(_id);
+ if (!row) { continue; }
+ row.cells[3].textContent = packetsCount;
+ row.cells[4].textContent = tossupsCount;
+ row.cells[5].textContent = bonusesCount;
}
});
diff --git a/client/scripts/utilities/tables.js b/client/scripts/utilities/tables.js
index 13ba079d8..48266c33d 100644
--- a/client/scripts/utilities/tables.js
+++ b/client/scripts/utilities/tables.js
@@ -31,13 +31,13 @@ export default function sortTable (n, numeric = false, tableId = 'table', header
based on the direction, asc or desc: */
if (dir === 'asc') {
if (numeric) {
- if (parseFloat(x.innerHTML) < parseFloat(y.innerHTML)) {
+ if (parseFloat(x.textContent) < parseFloat(y.textContent)) {
// If so, mark as a switch and break the loop:
shouldSwitch = true;
break;
}
} else {
- if (x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()) {
+ if (x.textContent.toLowerCase() > y.textContent.toLowerCase()) {
// If so, mark as a switch and break the loop:
shouldSwitch = true;
break;
@@ -45,13 +45,13 @@ export default function sortTable (n, numeric = false, tableId = 'table', header
}
} else if (dir === 'desc') {
if (numeric) {
- if (parseFloat(x.innerHTML) > parseFloat(y.innerHTML)) {
+ if (parseFloat(x.textContent) > parseFloat(y.textContent)) {
// If so, mark as a switch and break the loop:
shouldSwitch = true;
break;
}
} else {
- if (x.innerHTML.toLowerCase() < y.innerHTML.toLowerCase()) {
+ if (x.textContent.toLowerCase() < y.textContent.toLowerCase()) {
// If so, mark as a switch and break the loop:
shouldSwitch = true;
break;