feat(accounts): "Alle ausklappen" / "Alle einklappen" toggle for hoster groups
Adds a bottom-right button under the accounts list that expands every hoster group at once (and collapses them again — the label flips based on current state). Reuses the existing _hosterGroupOpenMemory so the per-group open/closed state stays consistent with manual header clicks. The footer is hidden when no accounts exist. Pure DOM toggle, no re-render. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
05ad08433c
commit
33364168f1
@ -3485,12 +3485,15 @@ function renderAccounts() {
|
||||
const runCheckBtn = document.getElementById('accountsRunHealthCheckBtn');
|
||||
if (runCheckBtn) runCheckBtn.disabled = healthCheckRunning;
|
||||
|
||||
const footer = document.getElementById('accountsListFooter');
|
||||
|
||||
if (allAccounts.length === 0) {
|
||||
container.innerHTML = `
|
||||
<div class="accounts-empty">
|
||||
<p>Keine Accounts vorhanden</p>
|
||||
<span class="hint">Klicke auf "Account hinzufügen", um einen Hoster einzurichten.</span>
|
||||
</div>`;
|
||||
if (footer) footer.style.display = 'none';
|
||||
if (!_accountListenersBound) bindAccountListeners(container);
|
||||
return;
|
||||
}
|
||||
@ -3509,6 +3512,9 @@ function renderAccounts() {
|
||||
}
|
||||
container.innerHTML = html;
|
||||
|
||||
if (footer) footer.style.display = '';
|
||||
_updateToggleAllAccountsBtn();
|
||||
|
||||
if (!_accountListenersBound) bindAccountListeners(container);
|
||||
}
|
||||
|
||||
@ -3578,6 +3584,35 @@ function _hosterLifetimeStat(name) {
|
||||
}
|
||||
function _invalidateHosterLifetimeCache() { _hosterLifetimeCache = null; }
|
||||
|
||||
function _allAccountGroupsOpen() {
|
||||
const bodies = document.querySelectorAll('#accountsList .account-hoster-group-body');
|
||||
if (!bodies.length) return false;
|
||||
for (const b of bodies) if (b.style.display === 'none') return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function _setAllAccountGroupsOpen(open) {
|
||||
const groups = document.querySelectorAll('#accountsList .account-hoster-group');
|
||||
groups.forEach(group => {
|
||||
const name = group.dataset.hosterGroup;
|
||||
const body = group.querySelector('.account-hoster-group-body');
|
||||
const arrow = group.querySelector('.panel-arrow');
|
||||
if (body) body.style.display = open ? '' : 'none';
|
||||
if (arrow) arrow.innerHTML = open ? '▼' : '▶';
|
||||
if (name) {
|
||||
const summary = _summarizeHosterGroup(config.hosters[name] || []);
|
||||
_hosterGroupOpenMemory.set(name, { state: open ? 'open' : 'closed', errorsAtClose: summary.error });
|
||||
}
|
||||
});
|
||||
_updateToggleAllAccountsBtn();
|
||||
}
|
||||
|
||||
function _updateToggleAllAccountsBtn() {
|
||||
const btn = document.getElementById('toggleAllAccountsBtn');
|
||||
if (!btn) return;
|
||||
btn.textContent = _allAccountGroupsOpen() ? 'Alle einklappen' : 'Alle ausklappen';
|
||||
}
|
||||
|
||||
// Single set of delegated listeners on the accounts container. Bound once on
|
||||
// the first render and reused for every subsequent in-place update / card
|
||||
// swap. Previously we rebound 4 × N button listeners + 5 × N drag listeners
|
||||
@ -4484,6 +4519,7 @@ function setupListeners() {
|
||||
document.getElementById('moveDownBtn').addEventListener('click', () => moveSelectedJobs('down'));
|
||||
document.getElementById('moveBottomBtn').addEventListener('click', () => moveSelectedJobs('bottom'));
|
||||
document.getElementById('accountsRunHealthCheckBtn').addEventListener('click', () => runHealthCheck('manual'));
|
||||
document.getElementById('toggleAllAccountsBtn').addEventListener('click', () => _setAllAccountGroupsOpen(!_allAccountGroupsOpen()));
|
||||
document.getElementById('copyAllLinksBtn').addEventListener('click', copyAllLinks);
|
||||
document.getElementById('clearRecentFilesBtn').addEventListener('click', clearAllRecentFiles);
|
||||
document.getElementById('exportRecentFilesBtn').addEventListener('click', exportAllRecentFiles);
|
||||
|
||||
@ -178,6 +178,9 @@
|
||||
</div>
|
||||
<div class="health-check-results account-health-results" id="healthCheckResults"></div>
|
||||
<div class="accounts-list" id="accountsList"></div>
|
||||
<div class="accounts-list-footer" id="accountsListFooter" style="display:none">
|
||||
<button class="btn btn-secondary" id="toggleAllAccountsBtn">Alle ausklappen</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -793,6 +793,7 @@ select.hs-input { max-width: none; width: auto; min-width: 140px; }
|
||||
padding: 0 0 12px;
|
||||
}
|
||||
.accounts-list { display: grid; gap: 8px; }
|
||||
.accounts-list-footer { display: flex; justify-content: flex-end; margin-top: 12px; }
|
||||
|
||||
.account-card {
|
||||
display: flex;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user