feat: show import-pending red lozenge when Sonarr/Radarr has issues
All checks were successful
Build and Push Docker Image / build (push) Successful in 23s

- Detect trackedDownloadState=importPending or status=warning/error
- Extract statusMessages and errorMessage from queue records
- Display red 'Import Pending' badge on download card header
- Hover reveals tooltip with the specific issue messages
- Visible to all users (not admin-only)
This commit is contained in:
2026-05-15 23:23:25 +01:00
parent efa66b9fd6
commit eda9770f49
3 changed files with 71 additions and 0 deletions

View File

@@ -59,6 +59,29 @@ function tagMatchesUser(tag, username) {
return false;
}
// Extract import issues from a Sonarr/Radarr queue record
function getImportIssues(queueRecord) {
if (!queueRecord) return null;
const state = queueRecord.trackedDownloadState;
const status = queueRecord.trackedDownloadStatus;
if (state !== 'importPending' && status !== 'warning' && status !== 'error') return null;
const messages = [];
if (queueRecord.statusMessages && queueRecord.statusMessages.length > 0) {
for (const sm of queueRecord.statusMessages) {
if (sm.messages && sm.messages.length > 0) {
messages.push(...sm.messages);
} else if (sm.title) {
messages.push(sm.title);
}
}
}
if (queueRecord.errorMessage) {
messages.push(queueRecord.errorMessage);
}
if (messages.length === 0) return null;
return messages;
}
// Helper to build Sonarr web UI link for a series
function getSonarrLink(series) {
if (!series || !series._instanceUrl || !series.titleSlug) return null;
@@ -355,6 +378,8 @@ router.get('/user-downloads', async (req, res) => {
episodeInfo: sonarrMatch,
userTag: userTag
};
const issues = getImportIssues(sonarrMatch);
if (issues) dlObj.importIssues = issues;
if (isAdmin) {
dlObj.downloadPath = slot.storage || null;
dlObj.targetPath = series.path || null;
@@ -391,6 +416,8 @@ router.get('/user-downloads', async (req, res) => {
movieInfo: radarrMatch,
userTag: userTag
};
const issues = getImportIssues(radarrMatch);
if (issues) dlObj.importIssues = issues;
if (isAdmin) {
dlObj.downloadPath = slot.storage || null;
dlObj.targetPath = movie.path || null;
@@ -536,6 +563,8 @@ router.get('/user-downloads', async (req, res) => {
download.seriesName = series.title;
download.episodeInfo = sonarrMatch;
download.userTag = userTag;
const sonarrIssues = getImportIssues(sonarrMatch);
if (sonarrIssues) download.importIssues = sonarrIssues;
if (isAdmin) {
download.downloadPath = download.savePath || null;
download.targetPath = series.path || null;
@@ -565,6 +594,8 @@ router.get('/user-downloads', async (req, res) => {
download.movieName = movie.title;
download.movieInfo = radarrMatch;
download.userTag = userTag;
const radarrIssues = getImportIssues(radarrMatch);
if (radarrIssues) download.importIssues = radarrIssues;
if (isAdmin) {
download.downloadPath = download.savePath || null;
download.targetPath = movie.path || null;