Add pagination/search/sort to the admin tables that can grow large
Uses simple-datatables (vanilla JS, no jQuery needed) on the Users, Sessions, Email Log, and Feedback tables, since those grow with real usage. Left Games (small, admin-curated) and Hints (row order is meaningful - "checked in order" - a sortable column would mislead) untouched. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,22 @@
|
|||||||
|
import { DataTable } from 'simple-datatables';
|
||||||
|
import 'simple-datatables/dist/style.css';
|
||||||
|
|
||||||
|
// Paginate/search/sort any admin table opted in via class="admin-datatable".
|
||||||
|
// Kept off tables that are admin-curated and stay small (games) or where row
|
||||||
|
// order is meaningful and must not be disturbed by sorting (hints).
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
document.querySelectorAll('table.admin-datatable').forEach((table) => {
|
||||||
|
new DataTable(table, {
|
||||||
|
perPage: 25,
|
||||||
|
perPageSelect: [10, 25, 50, 100],
|
||||||
|
searchable: true,
|
||||||
|
sortable: true,
|
||||||
|
labels: {
|
||||||
|
placeholder: 'Search...',
|
||||||
|
perPage: '{select} entries per page',
|
||||||
|
noRows: 'No matching entries found',
|
||||||
|
info: 'Showing {start} to {end} of {rows} entries',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -8,3 +8,4 @@ import 'bootstrap/js/dist/dropdown';
|
|||||||
import './game-waiting';
|
import './game-waiting';
|
||||||
import './game-lobby';
|
import './game-lobby';
|
||||||
import './admin-session-tabs';
|
import './admin-session-tabs';
|
||||||
|
import './admin-datatables';
|
||||||
|
|||||||
Generated
+24
-1
@@ -11,7 +11,8 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@popperjs/core": "^2.11.8",
|
"@popperjs/core": "^2.11.8",
|
||||||
"bootstrap": "^5.3.8",
|
"bootstrap": "^5.3.8",
|
||||||
"bootstrap-icons": "^1.13.1"
|
"bootstrap-icons": "^1.13.1",
|
||||||
|
"simple-datatables": "^10.3.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.25.0",
|
"@babel/core": "^7.25.0",
|
||||||
@@ -4013,6 +4014,12 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "CC0-1.0"
|
"license": "CC0-1.0"
|
||||||
},
|
},
|
||||||
|
"node_modules/dayjs": {
|
||||||
|
"version": "1.11.23",
|
||||||
|
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.23.tgz",
|
||||||
|
"integrity": "sha512-QDTCU0M0MxR3hQfnlDJfwekQiaanm1ubOD231u73WBckQ/fsamwRLiE2GBz6D3a/xF1NgfiDLJjXBa1hYOYTtQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/debug": {
|
"node_modules/debug": {
|
||||||
"version": "4.4.3",
|
"version": "4.4.3",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
|
||||||
@@ -4112,6 +4119,12 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/diff-dom": {
|
||||||
|
"version": "5.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/diff-dom/-/diff-dom-5.2.1.tgz",
|
||||||
|
"integrity": "sha512-G6WquwIa/XOxiYDYRMxfJj+c+a6LXMv7zgXoAQ3eRjTYkc8Lc4Aq97krTu/B15r243FR7dyeSxDenzKtO6sbfA==",
|
||||||
|
"license": "LGPL-3.0"
|
||||||
|
},
|
||||||
"node_modules/dns-packet": {
|
"node_modules/dns-packet": {
|
||||||
"version": "5.6.1",
|
"version": "5.6.1",
|
||||||
"resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz",
|
"resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz",
|
||||||
@@ -7706,6 +7719,16 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
|
"node_modules/simple-datatables": {
|
||||||
|
"version": "10.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/simple-datatables/-/simple-datatables-10.3.0.tgz",
|
||||||
|
"integrity": "sha512-/9XcZ/AzZWYNMTTwUcUqsNhZXD1KIHg4tWCUhRx5qPDOnRVG2gNdRDR1euNTCbQxfAypu78ucgWc/BOMFfuxAQ==",
|
||||||
|
"license": "LGPL-3.0",
|
||||||
|
"dependencies": {
|
||||||
|
"dayjs": "^1.11.21",
|
||||||
|
"diff-dom": "5.2.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/sockjs": {
|
"node_modules/sockjs": {
|
||||||
"version": "0.3.24",
|
"version": "0.3.24",
|
||||||
"resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz",
|
"resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz",
|
||||||
|
|||||||
+2
-1
@@ -27,6 +27,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@popperjs/core": "^2.11.8",
|
"@popperjs/core": "^2.11.8",
|
||||||
"bootstrap": "^5.3.8",
|
"bootstrap": "^5.3.8",
|
||||||
"bootstrap-icons": "^1.13.1"
|
"bootstrap-icons": "^1.13.1",
|
||||||
|
"simple-datatables": "^10.3.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,6 +48,40 @@
|
|||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* simple-datatables theming to match the admin panel */
|
||||||
|
.datatable-top,
|
||||||
|
.datatable-bottom {
|
||||||
|
padding: 0.75rem 1rem;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
color: #64748b;
|
||||||
|
}
|
||||||
|
.datatable-input {
|
||||||
|
border: 1px solid #e2e8f0;
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 0.35rem 0.6rem;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
}
|
||||||
|
.datatable-selector {
|
||||||
|
border: 1px solid #e2e8f0;
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 0.25rem 0.4rem;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
}
|
||||||
|
.datatable-pagination a,
|
||||||
|
.datatable-pagination button {
|
||||||
|
border-radius: 4px;
|
||||||
|
color: #475569;
|
||||||
|
}
|
||||||
|
.datatable-pagination a:hover,
|
||||||
|
.datatable-pagination button:hover {
|
||||||
|
background: #f1f5f9;
|
||||||
|
}
|
||||||
|
.datatable-pagination .datatable-active a,
|
||||||
|
.datatable-pagination .datatable-active button {
|
||||||
|
background: #3b82f6;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 767.98px) {
|
@media (max-width: 767.98px) {
|
||||||
.admin-shell {
|
.admin-shell {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="background: #fff; border-radius: 8px; box-shadow: 0 1px 3px rgba(0,0,0,.07); overflow: hidden;">
|
<div style="background: #fff; border-radius: 8px; box-shadow: 0 1px 3px rgba(0,0,0,.07); overflow: hidden;">
|
||||||
<table style="width: 100%; min-width: 620px; border-collapse: collapse; font-size: 0.9rem;">
|
<table class="admin-datatable" style="width: 100%; min-width: 620px; border-collapse: collapse; font-size: 0.9rem;">
|
||||||
<thead>
|
<thead>
|
||||||
<tr style="background: #f1f5f9; border-bottom: 1px solid #e2e8f0;">
|
<tr style="background: #f1f5f9; border-bottom: 1px solid #e2e8f0;">
|
||||||
<th style="padding: 0.75rem 1rem; text-align: left; color: #475569; font-weight: 600;">ID</th>
|
<th style="padding: 0.75rem 1rem; text-align: left; color: #475569; font-weight: 600;">ID</th>
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="background: #fff; border-radius: 8px; box-shadow: 0 1px 3px rgba(0,0,0,.07); overflow: hidden;">
|
<div style="background: #fff; border-radius: 8px; box-shadow: 0 1px 3px rgba(0,0,0,.07); overflow: hidden;">
|
||||||
<table style="width: 100%; min-width: 760px; border-collapse: collapse; font-size: 0.9rem;">
|
<table class="admin-datatable" style="width: 100%; min-width: 760px; border-collapse: collapse; font-size: 0.9rem;">
|
||||||
<thead>
|
<thead>
|
||||||
<tr style="background: #f1f5f9; border-bottom: 1px solid #e2e8f0;">
|
<tr style="background: #f1f5f9; border-bottom: 1px solid #e2e8f0;">
|
||||||
<th style="padding: 0.75rem 1rem; text-align: left; color: #475569; font-weight: 600;">Game</th>
|
<th style="padding: 0.75rem 1rem; text-align: left; color: #475569; font-weight: 600;">Game</th>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="background: #fff; border-radius: 8px; box-shadow: 0 1px 3px rgba(0,0,0,.07); overflow: hidden;">
|
<div style="background: #fff; border-radius: 8px; box-shadow: 0 1px 3px rgba(0,0,0,.07); overflow: hidden;">
|
||||||
<table style="width: 100%; min-width: 700px; border-collapse: collapse; font-size: 0.9rem;">
|
<table class="admin-datatable" style="width: 100%; min-width: 700px; border-collapse: collapse; font-size: 0.9rem;">
|
||||||
<thead>
|
<thead>
|
||||||
<tr style="background: #f1f5f9; border-bottom: 1px solid #e2e8f0;">
|
<tr style="background: #f1f5f9; border-bottom: 1px solid #e2e8f0;">
|
||||||
<th style="padding: 0.75rem 1rem; text-align: left; color: #475569; font-weight: 600;">ID</th>
|
<th style="padding: 0.75rem 1rem; text-align: left; color: #475569; font-weight: 600;">ID</th>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="background: #fff; border-radius: 8px; box-shadow: 0 1px 3px rgba(0,0,0,.07); overflow: hidden;">
|
<div style="background: #fff; border-radius: 8px; box-shadow: 0 1px 3px rgba(0,0,0,.07); overflow: hidden;">
|
||||||
<table style="width: 100%; min-width: 760px; border-collapse: collapse; font-size: 0.9rem;">
|
<table class="admin-datatable" style="width: 100%; min-width: 760px; border-collapse: collapse; font-size: 0.9rem;">
|
||||||
<thead>
|
<thead>
|
||||||
<tr style="background: #f1f5f9; border-bottom: 1px solid #e2e8f0;">
|
<tr style="background: #f1f5f9; border-bottom: 1px solid #e2e8f0;">
|
||||||
<th style="padding: 0.75rem 1rem; text-align: left; color: #475569; font-weight: 600;">ID</th>
|
<th style="padding: 0.75rem 1rem; text-align: left; color: #475569; font-weight: 600;">ID</th>
|
||||||
|
|||||||
Reference in New Issue
Block a user