dataforth/testdatadb UI: clear, persistent push feedback (toasts)
The push handlers set the button to 'skipped' then immediately ran search(), which re-rendered the inspector and wiped the text — so a skipped publish flashed and vanished (looked like nothing happened). Replace with persistent toasts that state the outcome explicitly: Published / already up-to-date / Push failed / and for a skip, '<model> isn't renderable yet, so nothing was sent.' Only refresh the row on an actual publish so the message isn't clobbered. Same for the multi-select Re-push summary. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -150,6 +150,12 @@
|
||||
.viewer iframe{display:block;width:100%;min-height:100%;border:1px solid var(--border);border-radius:5px;background:#fff;
|
||||
box-shadow:0 1px 5px rgba(15,23,42,.10)}
|
||||
kbd{font-family:var(--mono);font-size:11px;background:#f1f5f9;border:1px solid var(--border-strong);border-bottom-width:2px;border-radius:4px;padding:0 5px;color:var(--ink-2)}
|
||||
/* ---------- toast ---------- */
|
||||
.toast{position:fixed;right:18px;bottom:18px;max-width:400px;z-index:60;display:flex;flex-direction:column;gap:8px}
|
||||
.toast .t{background:#fff;border:1px solid var(--border);border-left:4px solid var(--accent);border-radius:8px;box-shadow:0 8px 28px rgba(15,23,42,.18);padding:11px 13px 12px;font-size:12.5px;color:var(--ink-2);cursor:pointer;animation:tin .16s}
|
||||
.toast .t.ok{border-left-color:var(--pass-ink)} .toast .t.warn{border-left-color:#d97706} .toast .t.err{border-left-color:var(--fail-ink)}
|
||||
.toast .t b{display:block;margin-bottom:2px;color:var(--ink);font-size:13px}
|
||||
@keyframes tin{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
|
||||
/* ---------- responsive ---------- */
|
||||
@media (max-width:1180px){
|
||||
main{grid-template-columns:1fr 0}
|
||||
@@ -242,6 +248,7 @@
|
||||
<div class="viewer" id="viewer"></div>
|
||||
</aside>
|
||||
</main>
|
||||
<div class="toast" id="toast"></div>
|
||||
|
||||
<script>
|
||||
const API='';
|
||||
@@ -381,23 +388,31 @@ async function doUpload(payload){
|
||||
const r=await fetch(API+'/api/upload',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(payload)});
|
||||
const d=await r.json().catch(()=>({})); if(!r.ok) throw new Error(d.error||('HTTP '+r.status)); return d;
|
||||
}
|
||||
function showToast(title,msg,type){ const c=$('toast'); if(!c)return; const el=document.createElement('div');
|
||||
el.className='t '+(type||''); el.innerHTML='<b>'+esc(title)+'</b>'+(msg?esc(msg):''); el.onclick=()=>el.remove();
|
||||
c.appendChild(el); setTimeout(()=>{el.style.transition='opacity .3s';el.style.opacity='0';setTimeout(()=>el.remove(),320);}, type==='warn'||type==='err'?9000:5000); }
|
||||
async function pushWeb(id,btn){
|
||||
const r=state.rows.find(x=>x.id==id); const sn=r?r.serial_number:id;
|
||||
const r=state.rows.find(x=>x.id==id); const sn=r?r.serial_number:id; const mdl=r?r.model_number:'';
|
||||
if(!confirm('Publish '+sn+' to the public Dataforth website now?')) return;
|
||||
const t=btn.textContent; btn.disabled=true; btn.textContent='Publishing…';
|
||||
try{ const d=await doUpload({ids:[+id]});
|
||||
btn.textContent=d.errors?('✕ '+d.errors+' err'):(d.skipped&&!(d.created+d.updated+d.unchanged)?'skipped':'Published ✓');
|
||||
setTimeout(search,500); // refresh WEB status from the DB
|
||||
}catch(e){ btn.textContent='✕ '+e.message.slice(0,16); btn.disabled=false; }
|
||||
try{ const d=await doUpload({ids:[+id]}); const pub=(d.created||0)+(d.updated||0);
|
||||
if(pub>0){ showToast('Published — '+sn,'Sent to the public website.','ok'); setTimeout(search,400); }
|
||||
else if(d.errors){ showToast('Push failed — '+sn, d.errors+' error(s) from the website API.','err'); }
|
||||
else if(d.skipped){ showToast('Not published — '+sn, mdl+' isn’t renderable yet, so nothing was sent. This model still needs the render fix before it can publish.','warn'); }
|
||||
else if(d.unchanged){ showToast(sn+' already up to date','Already on the website — nothing changed.','ok'); }
|
||||
else { showToast('No change — '+sn, 'Nothing was published.','warn'); }
|
||||
}catch(e){ showToast('Push failed — '+sn, e.message,'err'); }
|
||||
btn.disabled=false; btn.textContent=t;
|
||||
}
|
||||
async function pushSelected(){
|
||||
const ids=[...state.checks].map(Number); if(!ids.length) return;
|
||||
if(!confirm('Publish '+ids.length+' selected serial(s) to the public Dataforth website now?')) return;
|
||||
const b=$('repushSel'),t=b.textContent; b.disabled=true; b.textContent='Publishing…';
|
||||
try{ const d=await doUpload({ids});
|
||||
b.textContent='✓ '+((d.created||0)+(d.updated||0))+' pushed'+(d.skipped?(' · '+d.skipped+' skip'):'');
|
||||
setTimeout(()=>{b.textContent=t;b.disabled=false;search();},1400);
|
||||
}catch(e){ b.textContent='✕ failed'; b.disabled=false; alert('Push failed: '+e.message); }
|
||||
try{ const d=await doUpload({ids}); const pub=(d.created||0)+(d.updated||0);
|
||||
showToast('Push complete', pub+' published · '+(d.unchanged||0)+' unchanged · '+(d.skipped||0)+' skipped (not renderable)'+(d.errors?(' · '+d.errors+' error'):'')+'.', d.errors?'err':(pub||d.unchanged?'ok':'warn'));
|
||||
if(pub) search();
|
||||
}catch(e){ showToast('Push failed', e.message,'err'); }
|
||||
b.disabled=false; b.textContent=t;
|
||||
}
|
||||
$('repushSel').onclick=pushSelected;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user