feat: add sort dropdown to discography modal filter bar

Date desc/asc and Name A-Z/Z-A options added to the filter bar.
Sorting reorders DOM nodes in place so checkbox selection state
is preserved across sort changes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
dlynas 2026-05-08 17:50:38 -04:00
parent fe6f196cac
commit 2ad847f94e
2 changed files with 33 additions and 1 deletions

View file

@ -2452,6 +2452,12 @@ async function openDiscographyModal() {
<button class="discog-filter active" data-type="single" onclick="toggleDiscogFilter(this)">Singles</button>
</div>
<div class="discog-select-actions">
<select class="discog-sort-select" onchange="sortDiscogGrid(this.value)">
<option value="date-desc">Date </option>
<option value="date-asc">Date </option>
<option value="name-asc">Name AZ</option>
<option value="name-desc">Name ZA</option>
</select>
<button class="discog-select-btn" onclick="discogSelectAll(true)">Select All</button>
<button class="discog-select-btn" onclick="discogSelectAll(false)">Deselect All</button>
</div>
@ -2500,7 +2506,10 @@ function _renderDiscogCard(release, index, completionData) {
const albumName = release.name || release.title || '';
return `
<label class="discog-card ${statusClass}" data-type="${release._type}" style="animation-delay:${index * 0.03}s">
<label class="discog-card ${statusClass}"
data-type="${release._type}"
data-year="${year || '0'}" data-name="${albumName.toLowerCase().replace(/"/g, '&quot;')}"
style="animation-delay:${index * 0.03}s">
<input type="checkbox" class="discog-card-cb" data-album-id="${release.id}" data-album-name="${_esc(albumName)}" data-tracks="${tracks}" ${checked ? 'checked' : ''} onchange="_updateDiscogFooterCount()">
<div class="discog-card-art">
${img ? `<img src="${img}" alt="" loading="lazy">` : '<div class="discog-card-art-placeholder">🎵</div>'}
@ -2524,6 +2533,20 @@ function toggleDiscogFilter(btn) {
_updateDiscogFooterCount();
}
function sortDiscogGrid(value) {
const grid = document.getElementById('discog-grid');
if (!grid) return;
const cards = Array.from(grid.querySelectorAll('.discog-card'));
cards.sort((a, b) => {
if (value === 'date-desc') return parseInt(b.dataset.year || '0') - parseInt(a.dataset.year || '0');
if (value === 'date-asc') return parseInt(a.dataset.year || '0') - parseInt(b.dataset.year || '0');
if (value === 'name-asc') return (a.dataset.name || '').localeCompare(b.dataset.name || '');
if (value === 'name-desc') return (b.dataset.name || '').localeCompare(a.dataset.name || '');
return 0;
});
cards.forEach(card => grid.appendChild(card));
}
function discogSelectAll(select) {
document.querySelectorAll('.discog-card-cb').forEach(cb => {
if (cb.closest('.discog-card').style.display !== 'none') {

View file

@ -46101,6 +46101,15 @@ textarea.enhanced-meta-field-input {
.discog-select-btn:hover { color: rgba(255,255,255,0.7); border-color: rgba(255,255,255,0.15); }
.discog-sort-select {
padding: 4px 8px; border-radius: 6px; font-size: 11px; font-weight: 600;
background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.08);
color: rgba(255,255,255,0.4); cursor: pointer; font-family: inherit;
appearance: none; -webkit-appearance: none;
}
.discog-sort-select:hover { color: rgba(255,255,255,0.7); border-color: rgba(255,255,255,0.15); }
.discog-sort-select option { background: #1a1a2e; color: #fff; }
/* Album grid */
.discog-section-header {
grid-column: 1 / -1;