Skip to content

Commit da344a3

Browse files
committed
Refactor Prowlarr UI and enhance indexers list display
- Removed outdated stats display and replaced it with a dynamic indexers list that updates based on the current status of indexers. - Implemented a new method to handle indexer details and error messages, improving user feedback during data retrieval. - Redesigned the Prowlarr card layout for better organization and visual clarity, including a dedicated section for indexers and their statuses. - Enhanced error handling to display appropriate messages in the indexers list when data fails to load.
1 parent 332a9a7 commit da344a3

File tree

2 files changed

+264
-95
lines changed

2 files changed

+264
-95
lines changed

frontend/static/js/new-main.js

Lines changed: 82 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -4702,51 +4702,8 @@ let huntarrUI = {
47024702
}
47034703
}
47044704

4705-
// Update stats display
4706-
const updateElement = (id, value, tooltip = '') => {
4707-
const element = document.getElementById(id);
4708-
if (element) {
4709-
element.textContent = value || '--';
4710-
if (tooltip) {
4711-
element.title = tooltip;
4712-
}
4713-
}
4714-
};
4715-
4716-
// Update basic stats
4717-
updateElement('prowlarr-active-indexers', stats.active_indexers);
4718-
updateElement('prowlarr-total-calls', stats.total_api_calls);
4719-
updateElement('prowlarr-throttled', stats.throttled_indexers);
4720-
updateElement('prowlarr-failed', stats.failed_indexers);
4721-
4722-
// Update detailed tooltips with indexer names if available
4723-
if (stats.indexer_details) {
4724-
const activeNames = stats.indexer_details.active?.map(idx => idx.name).join(', ') || 'None';
4725-
const throttledNames = stats.indexer_details.throttled?.map(idx => idx.name).join(', ') || 'None';
4726-
const failedNames = stats.indexer_details.failed?.map(idx => idx.name).join(', ') || 'None';
4727-
4728-
updateElement('prowlarr-active-indexers', stats.active_indexers, `Active: ${activeNames}`);
4729-
updateElement('prowlarr-throttled', stats.throttled_indexers, `Throttled: ${throttledNames}`);
4730-
updateElement('prowlarr-failed', stats.failed_indexers, `Failed: ${failedNames}`);
4731-
}
4732-
4733-
// Update health status
4734-
const healthStatus = document.getElementById('prowlarr-health-status');
4735-
if (healthStatus) {
4736-
healthStatus.textContent = stats.health_status || 'Unknown';
4737-
4738-
// Color-code health status
4739-
healthStatus.className = 'health-status-text';
4740-
if (stats.health_status?.includes('healthy')) {
4741-
healthStatus.style.color = '#10b981'; // Green
4742-
} else if (stats.health_status?.includes('throttled')) {
4743-
healthStatus.style.color = '#f59e0b'; // Amber
4744-
} else if (stats.health_status?.includes('failed') || stats.health_status?.includes('disabled')) {
4745-
healthStatus.style.color = '#ef4444'; // Red
4746-
} else {
4747-
healthStatus.style.color = '#9ca3af'; // Gray
4748-
}
4749-
}
4705+
// Update indexers list
4706+
this.updateIndexersList(stats.indexer_details)
47504707

47514708
} else {
47524709
// Handle error case
@@ -4761,31 +4718,95 @@ let huntarrUI = {
47614718
connectionStatus.className = 'status-badge error';
47624719
}
47634720

4764-
// Set all stats to error state
4765-
['prowlarr-active-indexers', 'prowlarr-total-calls', 'prowlarr-throttled', 'prowlarr-failed'].forEach(id => {
4766-
const element = document.getElementById(id);
4767-
if (element) {
4768-
element.textContent = '--';
4769-
element.title = data.message || 'Connection error';
4770-
}
4771-
});
4772-
4773-
const healthStatus = document.getElementById('prowlarr-health-status');
4774-
if (healthStatus) {
4775-
healthStatus.textContent = data.message || 'Connection error';
4776-
healthStatus.style.color = '#ef4444'; // Red
4777-
}
4721+
// Show error in indexers list
4722+
this.updateIndexersList(null, data.message || 'Connection error');
47784723
}
47794724
})
47804725
.catch(error => {
47814726
console.error('[huntarrUI] Error loading Prowlarr status:', error);
47824727

4783-
// Hide the card on error
4728+
// Show the card with error state
47844729
const prowlarrCard = document.getElementById('prowlarrStatusCard');
47854730
if (prowlarrCard) {
4786-
prowlarrCard.style.display = 'none';
4731+
prowlarrCard.style.display = 'block';
4732+
4733+
// Update connection status to error
4734+
const connectionStatus = document.getElementById('prowlarrConnectionStatus');
4735+
if (connectionStatus) {
4736+
connectionStatus.textContent = '🔴 Error';
4737+
connectionStatus.className = 'status-badge error';
4738+
}
4739+
4740+
// Show error in indexers list
4741+
this.updateIndexersList(null, 'Failed to load Prowlarr data');
47874742
}
47884743
});
4744+
},
4745+
4746+
// Update indexers list display
4747+
updateIndexersList: function(indexerDetails, errorMessage = null) {
4748+
const indexersList = document.getElementById('prowlarr-indexers-list');
4749+
if (!indexersList) return;
4750+
4751+
if (errorMessage) {
4752+
// Show error state
4753+
indexersList.innerHTML = `<div class="loading-text" style="color: #ef4444;">${errorMessage}</div>`;
4754+
return;
4755+
}
4756+
4757+
if (!indexerDetails || (!indexerDetails.active && !indexerDetails.throttled && !indexerDetails.failed)) {
4758+
// No indexers found
4759+
indexersList.innerHTML = '<div class="loading-text">No indexers configured</div>';
4760+
return;
4761+
}
4762+
4763+
// Combine all indexers and sort alphabetically
4764+
let allIndexers = [];
4765+
4766+
// Add active indexers
4767+
if (indexerDetails.active) {
4768+
allIndexers = allIndexers.concat(
4769+
indexerDetails.active.map(idx => ({ ...idx, status: 'active' }))
4770+
);
4771+
}
4772+
4773+
// Add throttled indexers
4774+
if (indexerDetails.throttled) {
4775+
allIndexers = allIndexers.concat(
4776+
indexerDetails.throttled.map(idx => ({ ...idx, status: 'throttled' }))
4777+
);
4778+
}
4779+
4780+
// Add failed indexers
4781+
if (indexerDetails.failed) {
4782+
allIndexers = allIndexers.concat(
4783+
indexerDetails.failed.map(idx => ({ ...idx, status: 'failed' }))
4784+
);
4785+
}
4786+
4787+
// Sort alphabetically by name
4788+
allIndexers.sort((a, b) => a.name.localeCompare(b.name));
4789+
4790+
if (allIndexers.length === 0) {
4791+
indexersList.innerHTML = '<div class="loading-text">No indexers found</div>';
4792+
return;
4793+
}
4794+
4795+
// Build the HTML for indexers list
4796+
const indexersHtml = allIndexers.map(indexer => {
4797+
const statusText = indexer.status === 'active' ? 'Active' :
4798+
indexer.status === 'throttled' ? 'Throttled' :
4799+
'Failed';
4800+
4801+
return `
4802+
<div class="indexer-item">
4803+
<span class="indexer-name">${indexer.name}</span>
4804+
<span class="indexer-status ${indexer.status}">${statusText}</span>
4805+
</div>
4806+
`;
4807+
}).join('');
4808+
4809+
indexersList.innerHTML = indexersHtml;
47894810
}
47904811
};
47914812

frontend/templates/components/home_section.html

Lines changed: 182 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,154 @@ <h3><i class="fas fa-download"></i> Swaparr Status</h3>
602602
font-weight: 500;
603603
color: #9ca3af;
604604
}
605+
606+
/* New Prowlarr Card Layout */
607+
.prowlarr-main-card {
608+
background-color: rgba(32, 38, 50, 0.6);
609+
border-radius: 8px;
610+
padding: 15px;
611+
margin-bottom: 15px;
612+
border: 1px solid rgba(90, 109, 137, 0.2);
613+
}
614+
615+
.prowlarr-header-section {
616+
display: flex;
617+
align-items: center;
618+
gap: 15px;
619+
}
620+
621+
.prowlarr-info {
622+
display: flex;
623+
flex-direction: column;
624+
gap: 8px;
625+
flex: 1;
626+
}
627+
628+
.prowlarr-info h4 {
629+
margin: 0;
630+
color: var(--text-primary);
631+
font-size: 1.2em;
632+
font-weight: 600;
633+
}
634+
635+
.prowlarr-subcards {
636+
display: grid;
637+
grid-template-columns: 1fr 1fr;
638+
gap: 15px;
639+
}
640+
641+
.prowlarr-subcard {
642+
background-color: rgba(24, 28, 37, 0.6);
643+
border-radius: 8px;
644+
border: 1px solid rgba(90, 109, 137, 0.2);
645+
overflow: hidden;
646+
}
647+
648+
.subcard-header {
649+
background-color: rgba(64, 70, 84, 0.6);
650+
padding: 10px 15px;
651+
border-bottom: 1px solid rgba(90, 109, 137, 0.2);
652+
}
653+
654+
.subcard-header h5 {
655+
margin: 0;
656+
color: var(--text-primary);
657+
font-size: 0.9em;
658+
font-weight: 600;
659+
display: flex;
660+
align-items: center;
661+
gap: 8px;
662+
}
663+
664+
.subcard-header i {
665+
font-size: 0.8em;
666+
color: var(--accent-color);
667+
}
668+
669+
.indexers-list {
670+
padding: 15px;
671+
max-height: 200px;
672+
overflow-y: auto;
673+
}
674+
675+
.indexer-item {
676+
display: flex;
677+
justify-content: space-between;
678+
align-items: center;
679+
padding: 8px 0;
680+
border-bottom: 1px solid rgba(90, 109, 137, 0.1);
681+
}
682+
683+
.indexer-item:last-child {
684+
border-bottom: none;
685+
}
686+
687+
.indexer-name {
688+
font-weight: 500;
689+
color: var(--text-primary);
690+
}
691+
692+
.indexer-status {
693+
font-size: 0.8em;
694+
padding: 2px 8px;
695+
border-radius: 4px;
696+
font-weight: 500;
697+
}
698+
699+
.indexer-status.active {
700+
background-color: rgba(16, 185, 129, 0.2);
701+
color: #10b981;
702+
}
703+
704+
.indexer-status.throttled {
705+
background-color: rgba(245, 158, 11, 0.2);
706+
color: #f59e0b;
707+
}
708+
709+
.indexer-status.failed {
710+
background-color: rgba(239, 68, 68, 0.2);
711+
color: #ef4444;
712+
}
713+
714+
.loading-text {
715+
color: var(--text-secondary);
716+
text-align: center;
717+
font-style: italic;
718+
}
719+
720+
.pending-content {
721+
padding: 40px 15px;
722+
text-align: center;
723+
}
724+
725+
.pending-text {
726+
font-size: 1.1em;
727+
font-weight: 600;
728+
color: var(--text-secondary);
729+
margin-bottom: 5px;
730+
}
731+
732+
.pending-subtitle {
733+
font-size: 0.8em;
734+
color: var(--text-tertiary);
735+
}
736+
737+
/* Mobile responsive */
738+
@media (max-width: 768px) {
739+
.prowlarr-subcards {
740+
grid-template-columns: 1fr;
741+
}
742+
743+
.prowlarr-header-section {
744+
flex-direction: column;
745+
text-align: center;
746+
gap: 10px;
747+
}
748+
749+
.indexers-list {
750+
max-height: 150px;
751+
}
752+
}
605753
</style>
606754

607755
<!-- Prowlarr Status Card -->
@@ -610,40 +758,40 @@ <h3><i class="fas fa-download"></i> Swaparr Status</h3>
610758
<h3><i class="fas fa-search"></i> Prowlarr Monitor</h3>
611759
<button id="refresh-prowlarr-data" class="action-button success"><i class="fas fa-sync-alt"></i> Refresh</button>
612760
</div>
613-
<div class="media-stats-container">
614-
<div class="prowlarr-stats-grid">
615-
<!-- Prowlarr Stats Card -->
616-
<div class="app-stats-card prowlarr">
617-
<div class="status-container">
618-
<span id="prowlarrConnectionStatus" class="status-badge">⚫ Disconnected</span>
619-
</div>
620-
<div class="app-content">
621-
<div class="app-icon-wrapper">
622-
<img src="./static/images/app-icons/sonarr.png" alt="Prowlarr Logo" class="app-logo" style="filter: hue-rotate(60deg);">
623-
</div>
624-
<h4>Prowlarr</h4>
625-
</div>
626-
<div class="stats-numbers">
627-
<div class="stat-box">
628-
<div class="stat-number" id="prowlarr-active-indexers">--</div>
629-
<div class="stat-label">Active Indexers</div>
630-
</div>
631-
<div class="stat-box">
632-
<div class="stat-number" id="prowlarr-total-calls">--</div>
633-
<div class="stat-label">Total API Calls</div>
634-
</div>
635-
<div class="stat-box">
636-
<div class="stat-number" id="prowlarr-throttled">--</div>
637-
<div class="stat-label">Throttled Indexers</div>
638-
</div>
639-
<div class="stat-box">
640-
<div class="stat-number" id="prowlarr-failed">--</div>
641-
<div class="stat-label">Failed Indexers</div>
642-
</div>
643-
</div>
644-
<div class="prowlarr-health-indicator">
645-
<div id="prowlarr-health-status" class="health-status-text">Checking connection...</div>
646-
</div>
761+
762+
<!-- Main Prowlarr Card -->
763+
<div class="prowlarr-main-card">
764+
<div class="prowlarr-header-section">
765+
<div class="app-icon-wrapper">
766+
<img src="./static/images/app-icons/sonarr.png" alt="Prowlarr Logo" class="app-logo" style="filter: hue-rotate(60deg);">
767+
</div>
768+
<div class="prowlarr-info">
769+
<h4>Prowlarr</h4>
770+
<span id="prowlarrConnectionStatus" class="status-badge">⚫ Disconnected</span>
771+
</div>
772+
</div>
773+
</div>
774+
775+
<!-- Sub Cards Container -->
776+
<div class="prowlarr-subcards">
777+
<!-- Left Sub-Card: Indexers List -->
778+
<div class="prowlarr-subcard prowlarr-indexers-card">
779+
<div class="subcard-header">
780+
<h5><i class="fas fa-list"></i> Indexers</h5>
781+
</div>
782+
<div class="indexers-list" id="prowlarr-indexers-list">
783+
<div class="loading-text">Loading indexers...</div>
784+
</div>
785+
</div>
786+
787+
<!-- Right Sub-Card: Pending -->
788+
<div class="prowlarr-subcard prowlarr-pending-card">
789+
<div class="subcard-header">
790+
<h5><i class="fas fa-clock"></i> Statistics</h5>
791+
</div>
792+
<div class="pending-content">
793+
<div class="pending-text">Pending</div>
794+
<div class="pending-subtitle">Coming soon</div>
647795
</div>
648796
</div>
649797
</div>

0 commit comments

Comments
 (0)