Dashboard Masticationpedia: differenze tra le versioni
Nessun oggetto della modifica |
Nessun oggetto della modifica |
||
| Riga 195: | Riga 195: | ||
</div> | </div> | ||
</div> | </div> | ||
<!-- ✅ Carica il file JS che gestisce tutto | |||
<!-- ✅ Carica il file JS che gestisce tutto | |||
<script src="/w/index.php?title=MediaWiki:CommonDashboard.js&action=raw&ctype=text/javascript"></script> | <script src="/w/index.php?title=MediaWiki:CommonDashboard.js&action=raw&ctype=text/javascript"></script> | ||
</html> | </html> | ||
--> | |||
<script> | |||
// === ChatGPT plus esteso (UI + Salva + Explorer) — INLINE === | |||
(function(){ | |||
const $ = s => document.querySelector(s); | |||
const panel = $('#chatgpt-plus'); | |||
if (!panel) return; | |||
const projectSel = $('#mpChatProject'); | |||
const modeSel = $('#mpChatMode'); | |||
const fileInput = $('#mpChatFile'); | |||
const drop = $('#mpChatDrop'); | |||
const filesBox = $('#mpChatFiles'); | |||
const promptEl = $('#mpChatPrompt'); | |||
const sendBtn = $('#mpChatSend'); | |||
const ansBox = $('#mpChatAnswer'); | |||
const clearBtn = $('#mpChatClear'); | |||
const copyBtn = $('#mpChatCopy'); | |||
const saveBtn = $('#mpChatSave'); | |||
// Explorer | |||
const refreshBtn = $('#mpChatRefresh'); | |||
const savedList = $('#mpSavedList'); | |||
let attached = []; | |||
function renderFiles(){ | |||
if (!filesBox) return; | |||
filesBox.innerHTML = attached.map(n => | |||
`<span style="border:1px solid #eee; border-radius:6px; padding:4px 6px; background:#fafafa; font-size:12px;">${n}</span>` | |||
).join(''); | |||
} | |||
function addFiles(list){ for (const f of list) attached.push(f.name); renderFiles(); } | |||
fileInput?.addEventListener('change', () => { | |||
if (fileInput.files?.length) addFiles(fileInput.files); | |||
fileInput.value = ''; | |||
}); | |||
['dragenter','dragover','dragleave','drop'].forEach(evt=>{ | |||
drop?.addEventListener(evt, e => { e.preventDefault(); e.stopPropagation(); }); | |||
}); | |||
drop?.addEventListener('drop', e => { | |||
const dt = e.dataTransfer; | |||
if (dt?.files?.length) addFiles(dt.files); | |||
}); | |||
sendBtn?.addEventListener('click', () => { | |||
const q = (promptEl.value||'').trim(); | |||
const project = projectSel?.value || 'Generazione_capitoli'; | |||
const mode = modeSel?.value || 'analysis'; | |||
if (!q) { ansBox.textContent = 'Scrivi la domanda nel box sopra.'; return; } | |||
ansBox.textContent = | |||
`✅ Pannello pronto\n\n` + | |||
`• Progetto: ${project}\n` + | |||
`• Modalità: ${mode}\n` + | |||
`• Domanda:\n${q}\n\n` + | |||
`• Allegati (solo elenco, non inviati):\n` + | |||
(attached.length ? ('- ' + attached.join('\n- ')) : '(nessuno)'); | |||
}); | |||
clearBtn?.addEventListener('click', () => { ansBox.textContent = ''; }); | |||
copyBtn?.addEventListener('click', async () => { | |||
const txt = ansBox.textContent || ''; | |||
if (!txt.trim()) return; | |||
try { await navigator.clipboard.writeText(txt); copyBtn.textContent='Copiato!'; setTimeout(()=>copyBtn.textContent='Copia risposta',1200); } | |||
catch { alert('Impossibile copiare negli appunti.'); } | |||
}); | |||
saveBtn?.addEventListener('click', async () => { | |||
const project = projectSel?.value || 'Generazione_capitoli'; | |||
const content = ansBox.textContent || ''; | |||
if (!content.trim()){ alert('Nessuna risposta da salvare.'); return; } | |||
try { | |||
const r = await fetch('/dashboard/api/save_output.php', { | |||
method:'POST', | |||
headers:{'Content-Type':'application/json'}, | |||
body: JSON.stringify({ project, content }) | |||
}); | |||
const j = await r.json(); | |||
if (!j.ok) throw new Error(j.error||'Errore salvataggio'); | |||
alert('Risposta salvata: ' + j.file); | |||
await refreshList(); // aggiorna elenco dopo salvataggio | |||
} catch (e){ | |||
alert('Salvataggio non ancora configurato (manca save_output.php).'); | |||
} | |||
}); | |||
async function refreshList(){ | |||
const project = projectSel?.value || 'Generazione_capitoli'; | |||
if (!savedList) return; | |||
savedList.innerHTML = '<em style="color:#777;">Aggiorno…</em>'; | |||
try { | |||
const r = await fetch('/dashboard/api/list_saved_output.php?project=' + encodeURIComponent(project) + '&sub=output'); | |||
const j = await r.json(); | |||
if (!j.ok) throw new Error(j.error||'Errore lista'); | |||
if (!j.files.length){ | |||
savedList.innerHTML = '<em style="color:#777;">Nessun file salvato.</em>'; | |||
return; | |||
} | |||
savedList.innerHTML = j.files.map(f=>{ | |||
const d = new Date(f.mtime*1000).toLocaleString(); | |||
return `<div class="mp-saved-item" data-name="${f.name}" style="display:flex; gap:8px; align-items:center; justify-content:space-between; border-bottom:1px dashed #eee; padding:4px 0;"> | |||
<span><a href="#" class="open" data-name="${f.name}">${f.name}</a> <span style="color:#888;">(${f.size} B, ${d})</span></span> | |||
<button class="open" data-name="${f.name}" title="Apri nel box Risposta">Apri</button> | |||
</div>`; | |||
}).join(''); | |||
savedList.querySelectorAll('.open').forEach(el=>{ | |||
el.addEventListener('click', async (ev)=>{ | |||
ev.preventDefault(); | |||
await openFile(el.getAttribute('data-name')); | |||
}); | |||
}); | |||
} catch(e){ | |||
savedList.innerHTML = '<span style="color:#c00;">Errore: '+e.message+'</span>'; | |||
} | |||
} | |||
async function openFile(name){ | |||
const project = projectSel?.value || 'Generazione_capitoli'; | |||
try{ | |||
const r = await fetch('/dashboard/api/read_saved_output.php', { | |||
method:'POST', | |||
headers:{'Content-Type':'application/json'}, | |||
body: JSON.stringify({ project, file: name }) | |||
}); | |||
const j = await r.json(); | |||
if (!j.ok) throw new Error(j.error||'Errore lettura'); | |||
ansBox.textContent = j.content || ''; | |||
} catch(e){ | |||
alert('Errore apertura file: ' + e.message); | |||
} | |||
} | |||
// Aggiorna quando apri il pannello (se usi toggleDashboardBox) | |||
const toggle = window.toggleDashboardBox; | |||
if (typeof toggle === 'function'){ | |||
window.toggleDashboardBox = function(id){ | |||
const res = toggle.apply(this, arguments); | |||
if (id === 'chatgpt-plus' && panel.style.display !== 'none'){ | |||
refreshList(); | |||
} | |||
return res; | |||
}; | |||
} | |||
// Bottone Aggiorna | |||
refreshBtn?.addEventListener('click', refreshList); | |||
// Primo popolamento | |||
document.addEventListener('DOMContentLoaded', refreshList); | |||
})(); | |||
</script> | |||
Versione delle 08:46, 7 set 2025
🔧 Dashboard Operativa – Masticationpedia
Centro di comando per progetti, API, file e backup