refactor(webhooks): Integrate webhooks panel into status card
All checks were successful
Build and Push Docker Image / build (push) Successful in 41s
Licence Check / Licence compatibility and copyright header verification (push) Successful in 59s
CI / Security audit (push) Successful in 1m20s
CI / Tests & coverage (push) Successful in 1m33s

- Moved webhooks-section to be inline with status-panel in HTML
- Updated toggleStatusPanel() to show/hide webhooks section for admin users
- Updated closeStatusPanel() to also hide webhooks section
- Removed webhooks visibility from showDashboard() - now tied to status panel
- Updated CSS to make webhooks section styling consistent with status panel:
  - Same border, border-radius, margin, box-shadow
  - Updated webhook-stats to use status-card styling (background, border)
- Webhooks metrics now display inline with status panel for admin users
This commit is contained in:
2026-05-19 21:20:34 +01:00
parent 3ef35a8c43
commit aeacadbe68
3 changed files with 69 additions and 58 deletions

View File

@@ -302,9 +302,7 @@ function showDashboard() {
sp.style.display = 'none'; sp.style.display = 'none';
sp.innerHTML = ''; sp.innerHTML = '';
document.getElementById('admin-controls').style.display = isAdmin ? 'flex' : 'none'; document.getElementById('admin-controls').style.display = isAdmin ? 'flex' : 'none';
// Show webhooks section for admin users // Note: webhooks-section visibility is controlled by toggleStatusPanel()
const webhooksSection = document.getElementById('webhooks-section');
if (webhooksSection) webhooksSection.style.display = isAdmin ? '' : 'none';
// Initialise days input from saved value // Initialise days input from saved value
const daysInput = document.getElementById('history-days'); const daysInput = document.getElementById('history-days');
if (daysInput) daysInput.value = historyDays; if (daysInput) daysInput.value = historyDays;
@@ -772,12 +770,19 @@ const STATUS_REFRESH_MS = 5000;
async function toggleStatusPanel() { async function toggleStatusPanel() {
const panel = document.getElementById('status-panel'); const panel = document.getElementById('status-panel');
const webhooksSection = document.getElementById('webhooks-section');
if (panel.style.display !== 'none') { if (panel.style.display !== 'none') {
panel.style.display = 'none'; panel.style.display = 'none';
if (webhooksSection) webhooksSection.style.display = 'none';
if (statusRefreshHandle) { clearInterval(statusRefreshHandle); statusRefreshHandle = null; } if (statusRefreshHandle) { clearInterval(statusRefreshHandle); statusRefreshHandle = null; }
return; return;
} }
panel.style.display = 'block'; panel.style.display = 'block';
// Show webhooks section for admin users
if (webhooksSection && isAdmin) {
webhooksSection.style.display = '';
await fetchWebhookStatus();
}
await refreshStatusPanel(); await refreshStatusPanel();
if (statusRefreshHandle) clearInterval(statusRefreshHandle); if (statusRefreshHandle) clearInterval(statusRefreshHandle);
statusRefreshHandle = setInterval(refreshStatusPanel, STATUS_REFRESH_MS); statusRefreshHandle = setInterval(refreshStatusPanel, STATUS_REFRESH_MS);
@@ -785,6 +790,8 @@ async function toggleStatusPanel() {
function closeStatusPanel() { function closeStatusPanel() {
document.getElementById('status-panel').style.display = 'none'; document.getElementById('status-panel').style.display = 'none';
const webhooksSection = document.getElementById('webhooks-section');
if (webhooksSection) webhooksSection.style.display = 'none';
if (statusRefreshHandle) { clearInterval(statusRefreshHandle); statusRefreshHandle = null; } if (statusRefreshHandle) { clearInterval(statusRefreshHandle); statusRefreshHandle = null; }
} }

View File

@@ -70,51 +70,7 @@
<div id="status-panel" class="status-panel" style="display: none;"></div> <div id="status-panel" class="status-panel" style="display: none;"></div>
<div id="error-message" class="error-message" style="display: none;"></div> <!-- Webhooks Configuration Panel (inline with status) -->
<div id="loading" class="loading" style="display: none;">Loading downloads...</div>
<div class="main-tabs">
<div class="tab-bar">
<button class="tab-btn active" data-tab="downloads">Active Downloads</button>
<button class="tab-btn" data-tab="history">Recently Completed</button>
</div>
<div class="tab-panel" id="tab-downloads">
<div class="downloads-container">
<div id="no-downloads" class="no-downloads" style="display: none;">
<p>No downloads found for your user.</p>
<p>Make sure your shows and movies are tagged with your username in Sonarr/Radarr.</p>
</div>
<div id="downloads-list" class="downloads-list"></div>
</div>
</div>
<div class="tab-panel" id="tab-history" style="display: none;">
<div class="history-container" id="history-container">
<div class="history-header">
<div class="history-controls">
<label class="history-days-label" for="history-days">Last</label>
<input type="number" id="history-days" class="history-days-input" value="7" min="1" max="90">
<span class="history-days-label">days</span>
<button id="history-refresh-btn" class="history-refresh-btn" title="Refresh history">&#8635;</button>
<label class="history-toggle-label" id="ignore-available-label" data-tooltip="Hide failed downloads where the item is already available on disk (i.e. a failed upgrade attempt)">
<input type="checkbox" id="ignore-available-toggle">
<span>Hide upgrade failures</span>
</label>
</div>
</div>
<div id="history-loading" class="history-loading" style="display: none;">Loading history...</div>
<div id="history-error" class="history-error" style="display: none;"></div>
<div id="no-history" class="no-history" style="display: none;">
<p>No completed downloads found in this period.</p>
</div>
<div id="history-list" class="history-list"></div>
</div>
</div>
</div>
<!-- Webhooks Configuration Panel -->
<div class="webhooks-section" id="webhooks-section" style="display: none;"> <div class="webhooks-section" id="webhooks-section" style="display: none;">
<div class="webhooks-header" id="webhooks-header"> <div class="webhooks-header" id="webhooks-header">
<h2>⚡ Webhooks Configuration</h2> <h2>⚡ Webhooks Configuration</h2>
@@ -173,6 +129,50 @@
</div> </div>
</div> </div>
<div id="error-message" class="error-message" style="display: none;"></div>
<div id="loading" class="loading" style="display: none;">Loading downloads...</div>
<div class="main-tabs">
<div class="tab-bar">
<button class="tab-btn active" data-tab="downloads">Active Downloads</button>
<button class="tab-btn" data-tab="history">Recently Completed</button>
</div>
<div class="tab-panel" id="tab-downloads">
<div class="downloads-container">
<div id="no-downloads" class="no-downloads" style="display: none;">
<p>No downloads found for your user.</p>
<p>Make sure your shows and movies are tagged with your username in Sonarr/Radarr.</p>
</div>
<div id="downloads-list" class="downloads-list"></div>
</div>
</div>
<div class="tab-panel" id="tab-history" style="display: none;">
<div class="history-container" id="history-container">
<div class="history-header">
<div class="history-controls">
<label class="history-days-label" for="history-days">Last</label>
<input type="number" id="history-days" class="history-days-input" value="7" min="1" max="90">
<span class="history-days-label">days</span>
<button id="history-refresh-btn" class="history-refresh-btn" title="Refresh history">&#8635;</button>
<label class="history-toggle-label" id="ignore-available-label" data-tooltip="Hide failed downloads where the item is already available on disk (i.e. a failed upgrade attempt)">
<input type="checkbox" id="ignore-available-toggle">
<span>Hide upgrade failures</span>
</label>
</div>
</div>
<div id="history-loading" class="history-loading" style="display: none;">Loading history...</div>
<div id="history-error" class="history-error" style="display: none;"></div>
<div id="no-history" class="no-history" style="display: none;">
<p>No completed downloads found in this period.</p>
</div>
<div id="history-list" class="history-list"></div>
</div>
</div>
</div>
<footer class="app-footer"> <footer class="app-footer">
<p>Ensure your media is tagged with your username in Sonarr/Radarr to match downloads to users.</p> <p>Ensure your media is tagged with your username in Sonarr/Radarr to match downloads to users.</p>
<a href="https://git.i3omb.com/Gandalf/sofarr" target="_blank" rel="noopener noreferrer" class="app-version" id="app-version"></a> <a href="https://git.i3omb.com/Gandalf/sofarr" target="_blank" rel="noopener noreferrer" class="app-version" id="app-version"></a>

View File

@@ -1520,9 +1520,11 @@ body {
/* ===== Webhooks Configuration ===== */ /* ===== Webhooks Configuration ===== */
.webhooks-section { .webhooks-section {
background: var(--surface); background: var(--surface);
border-radius: 12px; border: 1px solid var(--border);
box-shadow: 0 2px 8px var(--shadow); border-radius: 10px;
margin-bottom: 20px; padding: 0;
margin-bottom: 16px;
box-shadow: 0 2px 4px var(--shadow);
overflow: hidden; overflow: hidden;
} }
@@ -1548,6 +1550,15 @@ body {
font-weight: 600; font-weight: 600;
} }
/* Webhooks metrics styling to match status cards */
.webhook-stats {
background: var(--background);
border: 1px solid var(--border);
border-radius: 8px;
padding: 14px;
margin-top: 12px;
}
.webhooks-toggle { .webhooks-toggle {
font-size: 1rem; font-size: 1rem;
color: var(--text-muted); color: var(--text-muted);
@@ -1690,13 +1701,6 @@ body {
color: var(--text-muted); color: var(--text-muted);
} }
.webhook-stats {
margin-top: 12px;
padding: 12px;
background: var(--surface-alt);
border-radius: 8px;
}
.webhook-stats-title { .webhook-stats-title {
color: var(--text-muted); color: var(--text-muted);
font-size: 0.7rem; font-size: 0.7rem;