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

📁 Importa file dal server (semplificata)




📁 Carica File GPT