(function () { 'use strict'; const form = document.getElementById('workbenchForm'); const clearButton = document.getElementById('workbenchClear'); const status = document.getElementById('workbenchStatus'); const storageKey = 'dbn.caseWorkbench.v1'; let statusTimer = 0; if (!form) { return; } function setStatus(message) { if (!status) { return; } status.textContent = message; window.clearTimeout(statusTimer); statusTimer = window.setTimeout(function () { status.textContent = ''; }, 2200); } function collect() { const data = {}; const fields = form.querySelectorAll('input, select, textarea'); fields.forEach(function (field) { if (!field.name) { return; } if (field.type === 'checkbox') { if (!Array.isArray(data[field.name])) { data[field.name] = []; } if (field.checked) { data[field.name].push(field.value); } return; } data[field.name] = field.value; }); data.saved_at = new Date().toISOString(); return data; } function restore(data) { if (!data || typeof data !== 'object') { return; } const fields = form.querySelectorAll('input, select, textarea'); fields.forEach(function (field) { if (!field.name) { return; } if (field.type === 'checkbox') { const values = Array.isArray(data[field.name]) ? data[field.name] : []; field.checked = values.indexOf(field.value) !== -1; return; } if (Object.prototype.hasOwnProperty.call(data, field.name)) { field.value = data[field.name] || ''; } }); } function save() { try { window.sessionStorage.setItem(storageKey, JSON.stringify(collect())); setStatus('Saved in this browser session.'); } catch (error) { setStatus('Could not save this session locally.'); } } try { const raw = window.sessionStorage.getItem(storageKey); if (raw) { restore(JSON.parse(raw)); setStatus('Restored local workbench notes.'); } } catch (error) { window.sessionStorage.removeItem(storageKey); } form.addEventListener('input', save); form.addEventListener('change', save); if (clearButton) { clearButton.addEventListener('click', function () { window.sessionStorage.removeItem(storageKey); form.reset(); setStatus('Workbench session cleared.'); }); } }()); // ── My Documents panel ──────────────────────────────────────────────────────── (function () { 'use strict'; var panel = document.querySelector('[data-my-docs="true"]'); var list = document.getElementById('myDocsList'); if (!panel || !list) return; var lang = (window.DBN_TOOLS_LANG || 'en'); var i18n = { empty: { en: 'No documents uploaded yet. Upload PDFs, DOCX, or TXT files in the AI Chat sidebar.', no: 'Ingen dokumenter lastet opp ennå. Last opp PDF, DOCX eller TXT i AI-chattens sidepanel.', uk: 'Документів ще немає. Завантажте файли у бічній панелі AI-чату.', pl: 'Brak dokumentów. Prześlij pliki w panelu bocznym czatu AI.' }, remove: { en: 'Remove', no: 'Fjern', uk: 'Видалити', pl: 'Usuń' }, ai: { en: 'AI Chat', no: 'AI-chat', uk: 'AI-чат', pl: 'Czat AI' }, tools: { en: 'Tools', no: 'Verktøy', uk: 'Інструменти', pl: 'Narzędzia' }, error: { en: 'Could not load documents.', no: 'Kunne ikke laste dokumenter.', uk: 'Не вдалося завантажити документи.', pl: 'Nie można załadować dokumentów.' }, }; function t(key) { return (i18n[key] && i18n[key][lang]) || (i18n[key] && i18n[key]['en']) || key; } function formatDate(str) { if (!str) return ''; try { return new Date(str).toLocaleDateString(); } catch (e) { return str; } } function renderDocs(docs) { if (!docs.length) { list.innerHTML = '

' + t('empty') + '

'; return; } list.innerHTML = docs.map(function (doc) { return '
' + '📄' + '' + esc(doc.filename) + '' + '' + esc(formatDate(doc.created_at)) + ' · ' + (doc.source === 'ai_chat' ? t('ai') : t('tools')) + '' + '' + '
'; }).join(''); list.querySelectorAll('.workbench-docs__remove').forEach(function (btn) { btn.addEventListener('click', function () { var docId = btn.getAttribute('data-doc-id'); if (!docId) return; btn.disabled = true; fetch('/api/user-docs.php?id=' + encodeURIComponent(docId), { method: 'DELETE', credentials: 'include' }) .then(function () { var item = list.querySelector('[data-doc-id="' + docId + '"]'); if (item) item.remove(); if (!list.querySelector('.workbench-docs__item')) { list.innerHTML = '

' + t('empty') + '

'; } }) .catch(function () { btn.disabled = false; }); }); }); } function esc(str) { return String(str).replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"'); } fetch('/api/user-docs.php', { credentials: 'include' }) .then(function (r) { return r.json(); }) .then(function (data) { if (data.ok) { renderDocs(data.docs || []); } else { list.innerHTML = '

' + t('error') + '

'; } }) .catch(function () { list.innerHTML = '

' + t('error') + '

'; }); }()); // ── Upload zone ─────────────────────────────────────────────────────────────── (function () { 'use strict'; var zone = document.getElementById('wbUploadZone'); var input = document.getElementById('wbUploadInput'); var status = document.getElementById('wbUploadStatus'); var list = document.getElementById('myDocsList'); if (!zone || !input) return; var lang = (window.DBN_TOOLS_LANG || 'en'); var statusTimer = 0; var i18n = { uploading: { en: 'Uploading…', no: 'Laster opp…', uk: 'Завантаження…', pl: 'Przesyłanie…' }, saved: { en: 'Saved.', no: 'Lagret.', uk: 'Збережено.', pl: 'Zapisano.' }, error: { en: 'Upload failed.', no: 'Opplasting mislyktes.', uk: 'Помилка завантаження.', pl: 'Błąd przesyłania.' }, remove: { en: 'Remove', no: 'Fjern', uk: 'Видалити', pl: 'Usuń' }, empty: { en: 'No documents yet.', no: 'Ingen dokumenter ennå.', uk: 'Документів ще немає.', pl: 'Brak dokumentów.' }, }; function t(key) { return (i18n[key] && i18n[key][lang]) || (i18n[key] && i18n[key]['en']) || key; } function esc(str) { return String(str).replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"'); } function setStatus(msg, keep) { if (!status) return; status.textContent = msg; window.clearTimeout(statusTimer); if (!keep) { statusTimer = window.setTimeout(function () { status.textContent = ''; }, 2400); } } function prependDoc(doc) { if (!list) return; var empty = list.querySelector('.workbench-docs__empty, .workbench-docs__loading'); if (empty) empty.remove(); var el = document.createElement('div'); el.className = 'workbench-docs__item'; el.setAttribute('role', 'listitem'); el.setAttribute('data-doc-id', doc.doc_id); el.innerHTML = '📄' + '' + esc(doc.filename) + '' + '' + esc(new Date(doc.created_at).toLocaleDateString()) + ' · workbench' + ''; el.querySelector('.workbench-docs__remove').addEventListener('click', function () { var btn = this; btn.disabled = true; fetch('/api/user-docs.php?id=' + encodeURIComponent(doc.doc_id), { method: 'DELETE', credentials: 'include' }) .then(function () { var item = list.querySelector('[data-doc-id="' + doc.doc_id + '"]'); if (item) item.remove(); if (!list.querySelector('.workbench-docs__item')) { list.innerHTML = '

' + t('empty') + '

'; } }) .catch(function () { btn.disabled = false; }); }); list.insertBefore(el, list.firstChild); } function uploadFile(file) { var fd = new FormData(); fd.append('file', file); setStatus(t('uploading'), true); return fetch('/api/user-docs.php', { method: 'POST', credentials: 'include', body: fd }) .then(function (r) { return r.json(); }) .then(function (data) { if (data.ok && data.doc) { prependDoc(data.doc); setStatus(t('saved')); } else { setStatus((data.error || t('error'))); } }) .catch(function () { setStatus(t('error')); }); } function handleFiles(files) { if (!files || !files.length) return; var chain = Promise.resolve(); Array.prototype.forEach.call(files, function (file) { chain = chain.then(function () { return uploadFile(file); }); }); } zone.addEventListener('dragover', function (e) { e.preventDefault(); zone.classList.add('is-drag-over'); }); zone.addEventListener('dragleave', function () { zone.classList.remove('is-drag-over'); }); zone.addEventListener('drop', function (e) { e.preventDefault(); zone.classList.remove('is-drag-over'); handleFiles(e.dataTransfer.files); }); input.addEventListener('change', function () { handleFiles(input.files); input.value = ''; }); }());