import { apiGet, apiDownloadFetch, apiUrl } from '../api.js';
import { canEdit, pageHeaderHTML, showToast } from '../app.js';
let questionnairesList = [];
let filterSearch = '';
export async function exportPage() {
const app = document.getElementById('app');
app.innerHTML = `
${pageHeaderHTML('Export Data')}
`;
try {
const data = await apiGet('questionnaires.php');
questionnairesList = data.questionnaires || [];
renderExport();
} catch (e) {
showToast(e.message, 'error');
document.getElementById('exportContent').innerHTML = `${esc(e.message)}
`;
}
}
function renderExport() {
const container = document.getElementById('exportContent');
if (!questionnairesList.length) {
container.innerHTML = `
No questionnaires
Create questionnaires first to export data.
`;
return;
}
const bundleBlock = canEdit() ? `
Export questionnaires (JSON)
Download all questionnaires with questions, answer options, and every translation.
Use Import questionnaires on the dashboard to restore this file on another server.
Export all questionnaires (JSON)
` : '';
container.innerHTML = `
${bundleBlock}
`;
document.getElementById('exportListSearch').addEventListener('input', (e) => {
filterSearch = e.target.value;
renderExportTableBody();
});
renderExportTableBody();
wireExportActions();
}
function exportRowSearchText(q) {
return [q.name, q.questionnaireID, q.version, q.state].filter(Boolean).join(' ');
}
function renderExportTableBody() {
const body = document.getElementById('exportTableBody');
const countEl = document.getElementById('exportListCount');
if (!body) return;
const q = filterSearch.trim().toLowerCase();
const filtered = q
? questionnairesList.filter(item => exportRowSearchText(item).toLowerCase().includes(q))
: questionnairesList;
if (!filtered.length) {
body.innerHTML = `
No questionnaires match
`;
if (countEl) {
countEl.textContent = q
? `0 of ${questionnairesList.length} questionnaires`
: '';
}
return;
}
body.innerHTML = filtered.map(item => exportRowHTML(item)).join('');
if (countEl) {
countEl.textContent = q
? `${filtered.length} of ${questionnairesList.length} questionnaires`
: `${questionnairesList.length} questionnaire${questionnairesList.length === 1 ? '' : 's'}`;
}
body.querySelectorAll('.export-btn').forEach(btn => {
btn.addEventListener('click', onExportCsvClick);
});
body.querySelectorAll('.export-btn-all').forEach(btn => {
btn.addEventListener('click', onExportAllVersionsClick);
});
}
function exportRowHTML(q) {
return `
${esc(q.name)}
${esc(q.version || '—')}
${esc(q.state || 'draft')}
${q.questionCount || 0}
${q.completedCount ?? 0}
Export current
All versions
Results
`;
}
function wireExportActions() {
document.getElementById('exportBundleBtn')?.addEventListener('click', async () => {
const btn = document.getElementById('exportBundleBtn');
btn.disabled = true;
const prev = btn.textContent;
btn.textContent = 'Preparing…';
try {
const res = await apiDownloadFetch(apiUrl('export?bundle=1'));
if (!res.ok) {
const err = await res.json().catch(() => ({}));
throw new Error(err.error?.message || err.error || 'Export failed');
}
const blob = await res.blob();
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
const stamp = new Date().toISOString().slice(0, 10);
a.download = `questionnaires_bundle_${stamp}.json`;
a.click();
URL.revokeObjectURL(url);
showToast('Questionnaire bundle downloaded', 'success');
} catch (e) {
showToast(e.message, 'error');
} finally {
btn.disabled = false;
btn.textContent = prev;
}
});
}
async function downloadExportCsv(btn, url, filename) {
const res = await apiDownloadFetch(url);
if (!res.ok) {
const err = await res.json().catch(() => ({ error: 'Download failed' }));
throw new Error(err.error?.message || err.error || 'Download failed');
}
const blob = await res.blob();
const blobUrl = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = blobUrl;
a.download = filename;
a.click();
URL.revokeObjectURL(blobUrl);
}
async function onExportCsvClick(ev) {
const btn = ev.currentTarget;
btn.disabled = true;
const prev = btn.textContent;
btn.textContent = 'Downloading…';
try {
const url = apiUrl(`export?questionnaireID=${encodeURIComponent(btn.dataset.id)}`);
await downloadExportCsv(btn, url, `${btn.dataset.name}_v${btn.dataset.version}.csv`);
showToast('Download started', 'success');
} catch (e) {
showToast(e.message, 'error');
} finally {
btn.disabled = false;
btn.textContent = prev;
}
}
async function onExportAllVersionsClick(ev) {
const btn = ev.currentTarget;
btn.disabled = true;
const prev = btn.textContent;
btn.textContent = 'Downloading…';
try {
const url = apiUrl(`export?questionnaireID=${encodeURIComponent(btn.dataset.id)}&allVersions=1`);
const stamp = new Date().toISOString().slice(0, 10);
await downloadExportCsv(btn, url, `${btn.dataset.name}_all_versions_${stamp}.csv`);
showToast('All versions download started', 'success');
} catch (e) {
showToast(e.message, 'error');
} finally {
btn.disabled = false;
btn.textContent = prev;
}
}
function esc(s) {
const d = document.createElement('div');
d.textContent = s ?? '';
return d.innerHTML;
}