Merge inline watch errors in place of alert()
All checks were successful
build-and-push / docker (push) Successful in 24s

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
dlawler489 2026-09-16 14:04:16 +10:00
commit 96497d79a8

View file

@ -2178,6 +2178,10 @@ function watchPanelHtml() {
const WATCH_STATUS = { ok: 'Up to date', checking: 'Checking…', error: 'Problem' }; const WATCH_STATUS = { ok: 'Up to date', checking: 'Checking…', error: 'Problem' };
// What went wrong with the last thing you asked a watch to do, shown on its row
// until the next attempt. Beats an alert() you can't read once it's dismissed.
const watchNotices = new Map();
function watchHtml(w) { function watchHtml(w) {
const when = w.last_checked_at ? `checked ${formatDate(w.last_checked_at)}` : 'not checked yet'; const when = w.last_checked_at ? `checked ${formatDate(w.last_checked_at)}` : 'not checked yet';
const listed = w.total != null && w.listed != null && w.listed < w.total const listed = w.total != null && w.listed != null && w.listed < w.total
@ -2199,6 +2203,7 @@ function watchHtml(w) {
<div class="watch-meta">${escapeHtml(when)} · every ${w.interval_hours}h · ${plural(w.imported_count, 'model')} imported${w.partial_count ? ` · ${w.partial_count} still without files` : ''}${w.error_count ? ` · ${w.error_count} failed` : ''}${listed}</div> <div class="watch-meta">${escapeHtml(when)} · every ${w.interval_hours}h · ${plural(w.imported_count, 'model')} imported${w.partial_count ? ` · ${w.partial_count} still without files` : ''}${w.error_count ? ` · ${w.error_count} failed` : ''}${listed}</div>
${w.last_error ? `<div class="ai-run-error">${escapeHtml(w.last_error)} ${w.last_error ? `<div class="ai-run-error">${escapeHtml(w.last_error)}
${w.last_error_reason === 'makerworld_token' ? '<button type="button" class="btn btn-primary btn-sm" data-watch="token">Update token</button>' : ''}</div>` : ''} ${w.last_error_reason === 'makerworld_token' ? '<button type="button" class="btn btn-primary btn-sm" data-watch="token">Update token</button>' : ''}</div>` : ''}
${watchNotices.has(w.id) ? `<div class="ai-run-error">${escapeHtml(watchNotices.get(w.id))}</div>` : ''}
${recent.length ? `<div class="watch-recent">${recent.map((i) => ` ${recent.length ? `<div class="watch-recent">${recent.map((i) => `
<span>${i.model_id <span>${i.model_id
? `<button type="button" class="link-btn" data-open-model="${i.model_id}">${escapeHtml(i.model_name || i.title || `Model ${i.model_id}`)}</button>` ? `<button type="button" class="link-btn" data-open-model="${i.model_id}">${escapeHtml(i.model_name || i.title || `Model ${i.model_id}`)}</button>`
@ -2288,6 +2293,7 @@ async function handleWatchAction(btn) {
const id = Number(btn.closest('[data-watch-id]').dataset.watchId); const id = Number(btn.closest('[data-watch-id]').dataset.watchId);
const action = btn.dataset.watch; const action = btn.dataset.watch;
btn.disabled = true; btn.disabled = true;
watchNotices.delete(id); // this attempt replaces whatever the last one said
try { try {
if (action === 'check') { if (action === 'check') {
await postJson(`/api/watches/${id}/check`); await postJson(`/api/watches/${id}/check`);
@ -2309,7 +2315,7 @@ async function handleWatchAction(btn) {
if (err.message && /token/i.test(err.message)) { if (err.message && /token/i.test(err.message)) {
promptMakerworldToken(err.message, () => retryWatchCheck(id), 'Save & check collection'); promptMakerworldToken(err.message, () => retryWatchCheck(id), 'Save & check collection');
} else { } else {
alert(err.message); watchNotices.set(id, err.message);
} }
} }
refreshWatches(); refreshWatches();