Spaces:
Running
Running
fix: manage panel stuck on 'Loading…' and visible to everyone
Browse filesThree bugs, all in the previous commit.
1. `.grid2{display:grid}` outranks the UA stylesheet's [hidden]{display:none} and the sheet had no [hidden] rule, so panel.hidden=true never hid anything: the panel rendered for every visitor, signed in or not. Added [hidden]{display:none!important}.
2. loadManage() returned early on a non-OK response and left the 'Loading…' placeholder on screen permanently. It now hides the panel and writes a real message.
3. loadManage() ran only at page load, so signing in afterwards never populated it. setUser() now re-runs it when the session becomes the owner, and clears it on sign-out.
- index.html +23 -6
index.html
CHANGED
|
@@ -145,6 +145,10 @@ table.board tbody tr:hover td:nth-child(1),table.board tbody tr:hover td:nth-chi
|
|
| 145 |
.note b{color:var(--ink-soft)}
|
| 146 |
|
| 147 |
/* queue + submit */
|
|
|
|
|
|
|
|
|
|
|
|
|
| 148 |
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:18px;margin-top:26px}
|
| 149 |
.grid2.one{grid-template-columns:1fr}
|
| 150 |
.panel{background:var(--surface);border:1px solid var(--border);border-radius:16px;padding:20px 22px}
|
|
@@ -705,6 +709,8 @@ function setUser(u,isOwner){
|
|
| 705 |
for(const id of ['visField','maxField','subtaskField']){
|
| 706 |
const el=document.getElementById(id); if(el)el.hidden=!isOwner;
|
| 707 |
}
|
|
|
|
|
|
|
| 708 |
if(!isOwner){
|
| 709 |
const vs=document.getElementById('f-vis'); if(vs)vs.value='public';
|
| 710 |
const mx=document.getElementById('f-max'); if(mx)mx.value='';
|
|
@@ -716,6 +722,7 @@ function setUser(u,isOwner){
|
|
| 716 |
for(const id of ['sourceField','visField','maxField','subtaskField']){
|
| 717 |
const el0=document.getElementById(id); if(el0)el0.hidden=true;
|
| 718 |
}
|
|
|
|
| 719 |
signinView.hidden=false; submitForm.hidden=true;
|
| 720 |
}
|
| 721 |
}
|
|
@@ -787,15 +794,22 @@ function mmsg(t,kind){const e=document.getElementById('manageMsg');
|
|
| 787 |
|
| 788 |
async function loadManage(){
|
| 789 |
const panel=document.getElementById('managePanel');
|
|
|
|
| 790 |
try{
|
| 791 |
const r=await fetch('/api/manage',{credentials:'same-origin'});
|
| 792 |
-
if(!r.ok){
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 793 |
const d=await r.json();
|
| 794 |
panel.hidden=false;
|
| 795 |
-
|
| 796 |
-
|
| 797 |
-
if(!
|
| 798 |
-
list.innerHTML=
|
| 799 |
const s=(m.status||'').toUpperCase();
|
| 800 |
const cls=s==='RUNNING'?'b-running':(s==='FAILED'||s==='REJECTED')?'b-failed':'b-pending';
|
| 801 |
const tags=[`<span class="badge ${cls}">${s}</span>`];
|
|
@@ -808,7 +822,10 @@ async function loadManage(){
|
|
| 808 |
<button class="mbtn danger" data-act="delete">Delete</button>
|
| 809 |
</div>`;}).join('');
|
| 810 |
list.querySelectorAll('button[data-act]').forEach(b=>b.onclick=()=>manageAct(b));
|
| 811 |
-
}catch(e){
|
|
|
|
|
|
|
|
|
|
| 812 |
}
|
| 813 |
|
| 814 |
async function manageAct(btn){
|
|
|
|
| 145 |
.note b{color:var(--ink-soft)}
|
| 146 |
|
| 147 |
/* queue + submit */
|
| 148 |
+
/* Author `display` rules (e.g. .grid2 below) outrank the UA stylesheet's
|
| 149 |
+
[hidden]{display:none}, so an element with class + hidden stays visible.
|
| 150 |
+
This restores the attribute as the last word. */
|
| 151 |
+
[hidden]{display:none!important}
|
| 152 |
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:18px;margin-top:26px}
|
| 153 |
.grid2.one{grid-template-columns:1fr}
|
| 154 |
.panel{background:var(--surface);border:1px solid var(--border);border-radius:16px;padding:20px 22px}
|
|
|
|
| 709 |
for(const id of ['visField','maxField','subtaskField']){
|
| 710 |
const el=document.getElementById(id); if(el)el.hidden=!isOwner;
|
| 711 |
}
|
| 712 |
+
// Signing in after page load must reveal the panel without a hard reload.
|
| 713 |
+
if(isOwner&&typeof loadManage==='function')loadManage();
|
| 714 |
if(!isOwner){
|
| 715 |
const vs=document.getElementById('f-vis'); if(vs)vs.value='public';
|
| 716 |
const mx=document.getElementById('f-max'); if(mx)mx.value='';
|
|
|
|
| 722 |
for(const id of ['sourceField','visField','maxField','subtaskField']){
|
| 723 |
const el0=document.getElementById(id); if(el0)el0.hidden=true;
|
| 724 |
}
|
| 725 |
+
const mp=document.getElementById('managePanel'); if(mp)mp.hidden=true;
|
| 726 |
signinView.hidden=false; submitForm.hidden=true;
|
| 727 |
}
|
| 728 |
}
|
|
|
|
| 794 |
|
| 795 |
async function loadManage(){
|
| 796 |
const panel=document.getElementById('managePanel');
|
| 797 |
+
const list=document.getElementById('manageList');
|
| 798 |
try{
|
| 799 |
const r=await fetch('/api/manage',{credentials:'same-origin'});
|
| 800 |
+
if(!r.ok){
|
| 801 |
+
// 401/403 = not signed in, or not the maintainer. Hide rather than explain:
|
| 802 |
+
// this panel simply does not exist for anyone else.
|
| 803 |
+
panel.hidden=true;
|
| 804 |
+
list.innerHTML='<div class="mrow" style="color:var(--ink-mute)">Sign in as the maintainer to manage models.</div>';
|
| 805 |
+
return;
|
| 806 |
+
}
|
| 807 |
const d=await r.json();
|
| 808 |
panel.hidden=false;
|
| 809 |
+
const models=Array.isArray(d.models)?d.models:[];
|
| 810 |
+
document.getElementById('manageCount').textContent=`${models.length} submitted`;
|
| 811 |
+
if(!models.length){list.innerHTML='<div class="mrow" style="color:var(--ink-mute)">Nothing submitted yet.</div>';return;}
|
| 812 |
+
list.innerHTML=models.map(m=>{
|
| 813 |
const s=(m.status||'').toUpperCase();
|
| 814 |
const cls=s==='RUNNING'?'b-running':(s==='FAILED'||s==='REJECTED')?'b-failed':'b-pending';
|
| 815 |
const tags=[`<span class="badge ${cls}">${s}</span>`];
|
|
|
|
| 822 |
<button class="mbtn danger" data-act="delete">Delete</button>
|
| 823 |
</div>`;}).join('');
|
| 824 |
list.querySelectorAll('button[data-act]').forEach(b=>b.onclick=()=>manageAct(b));
|
| 825 |
+
}catch(e){
|
| 826 |
+
panel.hidden=true;
|
| 827 |
+
list.innerHTML=`<div class="mrow" style="color:var(--ink-mute)">Could not load (${esc(String(e))}).</div>`;
|
| 828 |
+
}
|
| 829 |
}
|
| 830 |
|
| 831 |
async function manageAct(btn){
|