diff --git a/public/index.html b/public/index.html
index d3d7c00..ac236f5 100644
--- a/public/index.html
+++ b/public/index.html
@@ -578,7 +578,7 @@ body::before{content:'';position:fixed;inset:0;background:radial-gradient(ellips
-
+
@@ -869,10 +869,16 @@ async function api(method, url, body) {
// ============================================================
// NAVIGATION
// ============================================================
+let amppRefreshTimer = null;
function switchPage(name) {
document.querySelectorAll('.nav-tab').forEach(t => t.classList.toggle('active', t.dataset.page === name));
document.querySelectorAll('.page').forEach(p => p.classList.toggle('active', p.id === `page-${name}`));
- if (name === 'monitor') loadAmppJobs();
+ // Clear AMPP auto-refresh when leaving monitor page
+ if (amppRefreshTimer) { clearInterval(amppRefreshTimer); amppRefreshTimer = null; }
+ if (name === 'monitor') {
+ loadAmppJobs();
+ amppRefreshTimer = setInterval(loadAmppJobs, 30000);
+ }
if (name === 'admin') { loadUsers(); loadAdminFolders(); }
}
@@ -1126,21 +1132,40 @@ function setFileStatus(i,cls,text) { const el=document.getElementById(`stat-${i}
async function loadAmppJobs() {
const list=document.getElementById('job-list'); const status=document.getElementById('ampp-status');
status.className='status-msg loading'; status.textContent='Loading jobs…';
+ list.innerHTML='';
try {
const d = await api('GET','/api/ampp/jobs?limit=50');
- status.className='status-msg'; status.textContent='';
- if (!d.success) { status.className='status-msg error'; status.textContent=d.error||'Failed'; return; }
- const jobs=d.jobs?.items||d.jobs||[];
- if (!jobs.length) { list.innerHTML='No jobs found
'; return; }
- list.innerHTML='';
+ status.className=''; status.textContent='';
+ if (!d.success) {
+ // Check for "not configured" specifically — show a helpful prompt
+ if (d.error && d.error.toLowerCase().includes('not configured')) {
+ list.innerHTML=`
+
📡
+
AMPP not configured
+
Enter your AMPP base URL and API key in Admin settings to enable job monitoring.
+
+
`;
+ } else {
+ status.className='status-msg error'; status.textContent=`❌ ${d.error||'Failed to load jobs'}`;
+ }
+ return;
+ }
+ // AMPP returns { items: [...], total: N } or an array directly
+ const jobs=Array.isArray(d.jobs)?d.jobs:(d.jobs?.items||d.jobs?.results||[]);
+ if (!jobs.length) {
+ list.innerHTML='No jobs in queue
';
+ return;
+ }
jobs.forEach(job => {
const el=document.createElement('div'); el.className='job-item';
- const st=(job.status||job.state||'unknown').toLowerCase();
- const cls=st.includes('run')?'running':st.includes('complet')||st.includes('success')?'completed':st.includes('fail')||st.includes('error')?'failed':st.includes('queue')||st.includes('wait')?'queued':'unknown';
- el.innerHTML=`${esc(job.name||job.id||'Job')}
${job.created?new Date(job.created).toLocaleString():''}
${cls.charAt(0).toUpperCase()+cls.slice(1)}`;
+ const st=(job.status||job.state||job.jobStatus||'unknown').toLowerCase();
+ const cls=st.includes('run')||st.includes('active')?'running':st.includes('complet')||st.includes('success')||st.includes('done')?'completed':st.includes('fail')||st.includes('error')?'failed':st.includes('queue')||st.includes('wait')||st.includes('pend')?'queued':'unknown';
+ const name=job.name||job.displayName||job.id||'Job';
+ const meta=[job.created?new Date(job.created).toLocaleString():'', job.type||job.jobType||''].filter(Boolean).join(' · ');
+ el.innerHTML=`${cls.charAt(0).toUpperCase()+cls.slice(1)}`;
list.appendChild(el);
});
- } catch(e) { status.className='status-msg error'; status.textContent=e.message; list.innerHTML=''; }
+ } catch(e) { status.className='status-msg error'; status.textContent=`❌ ${e.message}`; list.innerHTML=''; }
}
// ============================================================
@@ -1214,7 +1239,7 @@ async function loadAmppConfig() {
} catch(_){}
}
async function testAmpp() {
- const s=document.getElementById('ampp-status');
+ const s=document.getElementById('ampp-cfg-status');
s.className='status-msg loading'; s.textContent='🔍 Testing AMPP connection…';
try {
const body={baseUrl:document.getElementById('ampp-base-url').value.trim()};
@@ -1225,7 +1250,7 @@ async function testAmpp() {
} catch(e){s.className='status-msg error';s.textContent=`❌ ${e.message}`;}
}
async function saveAmpp() {
- const s=document.getElementById('ampp-status');
+ const s=document.getElementById('ampp-cfg-status');
s.className='status-msg loading'; s.textContent='💾 Saving…';
try {
const body={baseUrl:document.getElementById('ampp-base-url').value.trim()};