fix: keep the queue filter layout stable

Reserve the reset action permanently inside the filter group, disabling and dimming it when no filter is active so typing never changes the toolbar width.
This commit is contained in:
Sucukdeluxe
2026-08-21 01:01:17 +02:00
parent e742a74f6d
commit 010b148141
5 changed files with 6 additions and 6 deletions
-1
View File
@@ -3940,7 +3940,6 @@ function syncQueueFilterResetAction() {
const button = document.getElementById('queueFilterResetBtn'); const button = document.getElementById('queueFilterResetBtn');
if (!button) return; if (!button) return;
const active = _hasActiveQueueFilters(); const active = _hasActiveQueueFilters();
button.hidden = !active;
button.disabled = !active; button.disabled = !active;
} }
+1 -1
View File
@@ -295,7 +295,7 @@
<select class="hs-input" id="queueStatusFilter" aria-label="Nach Status filtern" style="width:auto;min-width:150px"> <select class="hs-input" id="queueStatusFilter" aria-label="Nach Status filtern" style="width:auto;min-width:150px">
<option value="">Alle Status</option><option value="error">Nur Fehler</option><option value="active">Aktiv</option><option value="waiting">Wartend</option><option value="done">Erfolgreich</option> <option value="">Alle Status</option><option value="error">Nur Fehler</option><option value="active">Aktiv</option><option value="waiting">Wartend</option><option value="done">Erfolgreich</option>
</select> </select>
<button class="btn btn-xs btn-secondary queue-filter-reset" id="queueFilterResetBtn" hidden>Filter zurücksetzen</button> <button class="btn btn-xs btn-secondary queue-filter-reset" id="queueFilterResetBtn" disabled>Filter zurücksetzen</button>
</div> </div>
</div> </div>
+3 -2
View File
@@ -405,8 +405,9 @@ body {
margin-left: 2px; margin-left: 2px;
white-space: nowrap; white-space: nowrap;
} }
.queue-filter-reset[hidden] { .queue-filter-reset:disabled {
display: none; opacity: .45;
cursor: default;
} }
.queue-filter-bar { .queue-filter-bar {
min-width: 0; min-width: 0;
+1 -1
View File
@@ -177,7 +177,7 @@ test('header occupies its final geometry before asynchronous initialization', ()
assert.match(css, /\.update-dialog\s*\{[^}]*width:\s*min\(576px,\s*100%\);/su); assert.match(css, /\.update-dialog\s*\{[^}]*width:\s*min\(576px,\s*100%\);/su);
assert.match(css, /\.update-release-notes\s*\{[^}]*height:\s*min\(264px,\s*48vh\);/su); assert.match(css, /\.update-release-notes\s*\{[^}]*height:\s*min\(264px,\s*48vh\);/su);
assert.match(html, /class="update-progress-footer"[\s\S]*id="updateProgressDetails"[\s\S]*id="updateProgressSize"[\s\S]*id="updateProgressSpeed"[\s\S]*id="updateProgressEta"[\s\S]*id="updateProgressText"/u); assert.match(html, /class="update-progress-footer"[\s\S]*id="updateProgressDetails"[\s\S]*id="updateProgressSize"[\s\S]*id="updateProgressSpeed"[\s\S]*id="updateProgressEta"[\s\S]*id="updateProgressText"/u);
assert.match(html, /id="queueFilterResetBtn"[^>]*hidden[^>]*>Filter zurücksetzen</u); assert.match(html, /id="queueFilterResetBtn"[^>]*disabled[^>]*>Filter zurücksetzen</u);
assert.doesNotMatch(html, /<\/div>\s*<div class="queue-filter-bar"/u); assert.doesNotMatch(html, /<\/div>\s*<div class="queue-filter-bar"/u);
assert.match(css, /\.queue-filter-bar\s*\{[^}]*display:\s*flex;[^}]*margin-left:\s*auto;[^}]*border:\s*1px solid var\(--border\);[^}]*border-radius:\s*7px;/su); assert.match(css, /\.queue-filter-bar\s*\{[^}]*display:\s*flex;[^}]*margin-left:\s*auto;[^}]*border:\s*1px solid var\(--border\);[^}]*border-radius:\s*7px;/su);
assert.match(css, /#updateProgressDetails\s*\{[^}]*display:\s*grid;[^}]*grid-template-columns:\s*19ch 2ch 11ch 2ch 10ch;[^}]*column-gap:\s*0;[^}]*font-variant-numeric:\s*tabular-nums;/su); assert.match(css, /#updateProgressDetails\s*\{[^}]*display:\s*grid;[^}]*grid-template-columns:\s*19ch 2ch 11ch 2ch 10ch;[^}]*column-gap:\s*0;[^}]*font-variant-numeric:\s*tabular-nums;/su);
+1 -1
View File
@@ -754,7 +754,7 @@ setTimeout(async () => {
renderQueueTable(); renderQueueTable();
return { before, after }; return { before, after };
})()\`); })()\`);
check('Queue filter reset clears sidebar, search, host, and status together', queueFilterReset.before.hidden === false && queueFilterReset.before.disabled === false && queueFilterReset.after.hidden === true && queueFilterReset.after.disabled === true && queueFilterReset.after.sidebar === 'all' && queueFilterReset.after.search === '' && queueFilterReset.after.hoster === '' && queueFilterReset.after.status === '' && queueFilterReset.after.allPressed === 'true' && queueFilterReset.after.visible === 'filter-a|filter-b'); check('Queue filter reset clears every filter without shifting its stable action', queueFilterReset.before.hidden === false && queueFilterReset.before.disabled === false && queueFilterReset.after.hidden === false && queueFilterReset.after.disabled === true && queueFilterReset.after.sidebar === 'all' && queueFilterReset.after.search === '' && queueFilterReset.after.hoster === '' && queueFilterReset.after.status === '' && queueFilterReset.after.allPressed === 'true' && queueFilterReset.after.visible === 'filter-a|filter-b');
const queueSelectionAnchor = await wc.executeJavaScript(\`(() => { const queueSelectionAnchor = await wc.executeJavaScript(\`(() => {
queueJobs = ['a', 'b', 'c', 'd'].map(id => ({ id: 'anchor-' + id, file: 'C:/ui/anchor-' + id + '.bin', fileName: 'anchor-' + id + '.bin', hoster: 'byse.sx', status: 'queued', bytesUploaded: 0, bytesTotal: 100, progress: 0 })); queueJobs = ['a', 'b', 'c', 'd'].map(id => ({ id: 'anchor-' + id, file: 'C:/ui/anchor-' + id + '.bin', fileName: 'anchor-' + id + '.bin', hoster: 'byse.sx', status: 'queued', bytesUploaded: 0, bytesTotal: 100, progress: 0 }));