From cf00c9f7c55889f1ea390fa59afd67140618d837 Mon Sep 17 00:00:00 2001 From: Lukas Date: Sun, 7 Jun 2026 16:18:50 +0200 Subject: [PATCH] fix: keep search controls visible and enable suggestion click-to-resolve - Search input and button now stay visible after Search Again for unlimited searches - Clicking a suggestion populates provider key and triggers resolve, card disappears - Added data-provider-key attribute to suggestion links for click handling --- src/server/web/templates/unresolved.html | 74 +++++++++++++++++++++--- 1 file changed, 65 insertions(+), 9 deletions(-) diff --git a/src/server/web/templates/unresolved.html b/src/server/web/templates/unresolved.html index 829e986..64c204b 100644 --- a/src/server/web/templates/unresolved.html +++ b/src/server/web/templates/unresolved.html @@ -594,13 +594,13 @@ ? folder.search_suggestions.map(s => `
- ${s.name || s.title} + ${s.name || s.title}
`).join('') : '
No suggestions found
'; - const searchAgainBtn = (folder.search_suggestions && folder.search_suggestions.length === 0) - ? `
+ // Always show search row so user can search multiple times + const searchAgainBtn = `
Search Again -
` - : ''; +
`; return `
@@ -767,22 +766,79 @@ suggestionsEl.innerHTML = result.search_suggestions.map(s => ` `).join(''); } else { suggestionsEl.innerHTML = '
No suggestions found
'; } - // Remove the search row since we now have suggestions (or none) - const searchRow = item.querySelector('.search-again-row'); - if (searchRow) searchRow.remove(); + // Keep search row visible for additional searches + btn.classList.remove('searching'); + btn.innerHTML = ' Search Again'; } catch (err) { showToast('Search failed', 'error'); + btn.classList.remove('searching'); + btn.innerHTML = ' Search Again'; } finally { btn.classList.remove('searching'); } }); }); + + // Suggestion link click - populate input and resolve + document.querySelectorAll('.suggestion-link').forEach(link => { + link.addEventListener('click', async (e) => { + e.preventDefault(); + const providerKey = e.target.dataset.providerKey; + const folder = e.target.dataset.folder; + + if (!providerKey) { + showToast('No provider key available for this suggestion', 'error'); + return; + } + + const input = document.querySelector(`.folder-input[data-folder="${folder}"]`); + const resolveBtn = document.querySelector(`.resolve-btn[data-folder="${folder}"]`); + const item = document.querySelector(`.folder-item[data-folder="${folder}"]`); + const errEl = document.querySelector(`.folder-error[data-folder="${folder}"]`); + + if (!input || !resolveBtn || !item) return; + + // Populate input and enable button + input.value = providerKey; + resolveBtn.disabled = false; + + // Trigger resolve + item.classList.add('resolving'); + resolveBtn.disabled = true; + resolveBtn.innerHTML = ''; + + try { + const result = await resolveFolder(folder, providerKey); + + if (result.status === 'success') { + showToast(`Added: ${result.message.replace('Successfully resolved and added series: ', '')}`, 'success'); + item.classList.add('resolved'); + setTimeout(() => { + item.remove(); + checkEmptyList(); + }, 400); + } else { + errEl.textContent = result.detail || result.message || 'Failed to resolve'; + errEl.classList.add('visible'); + resolveBtn.disabled = false; + resolveBtn.innerHTML = 'Resolve'; + } + } catch (err) { + errEl.textContent = 'Server error. Please try again.'; + errEl.classList.add('visible'); + resolveBtn.disabled = false; + resolveBtn.innerHTML = 'Resolve'; + } finally { + item.classList.remove('resolving'); + } + }); + }); } function checkEmptyList() {