added quesionnaire export and import
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
import { apiGet, apiPut, apiDelete } from '../api.js';
|
||||
import { apiGet, apiPost, apiPut, apiDelete } from '../api.js';
|
||||
import { canEdit, showToast, getRole } from '../app.js';
|
||||
import { navigate } from '../router.js';
|
||||
|
||||
@ -14,8 +14,11 @@ export async function dashboardPage() {
|
||||
|
||||
if (canEdit()) {
|
||||
document.getElementById('headerActions').innerHTML = `
|
||||
<input type="file" id="importBundleFile" accept=".json,application/json" hidden>
|
||||
<button type="button" class="btn" id="importBundleBtn">Import questionnaires</button>
|
||||
<a href="#/questionnaire/new" class="btn btn-primary">+ New Questionnaire</a>
|
||||
`;
|
||||
bindImportBundle();
|
||||
}
|
||||
|
||||
try {
|
||||
@ -143,6 +146,61 @@ function initGridDrag(questionnaires) {
|
||||
});
|
||||
}
|
||||
|
||||
function bindImportBundle() {
|
||||
const fileInput = document.getElementById('importBundleFile');
|
||||
const btn = document.getElementById('importBundleBtn');
|
||||
if (!fileInput || !btn) return;
|
||||
|
||||
btn.addEventListener('click', () => fileInput.click());
|
||||
|
||||
fileInput.addEventListener('change', async () => {
|
||||
const file = fileInput.files?.[0];
|
||||
fileInput.value = '';
|
||||
if (!file) return;
|
||||
|
||||
let bundle;
|
||||
try {
|
||||
const text = await file.text();
|
||||
bundle = JSON.parse(text);
|
||||
} catch {
|
||||
showToast('Invalid JSON file', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!bundle?.questionnaires || !Array.isArray(bundle.questionnaires)) {
|
||||
showToast('Not a questionnaire bundle (missing questionnaires array)', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
const count = bundle.questionnaires.length;
|
||||
if (!confirm(`Import ${count} questionnaire(s) from this file?`)) return;
|
||||
const replace = confirm(
|
||||
'If a questionnaire ID from the file already exists:\n\n' +
|
||||
'OK — replace that questionnaire\n' +
|
||||
'Cancel — import as a new copy (new ID)'
|
||||
);
|
||||
|
||||
btn.disabled = true;
|
||||
const prev = btn.textContent;
|
||||
btn.textContent = 'Importing…';
|
||||
try {
|
||||
const result = await apiPost('questionnaires.php', {
|
||||
action: 'importBundle',
|
||||
bundle,
|
||||
replaceIfExists: replace,
|
||||
});
|
||||
const n = result.imported ?? count;
|
||||
showToast(`Imported ${n} questionnaire(s)`, 'success');
|
||||
await dashboardPage();
|
||||
} catch (e) {
|
||||
showToast(e.message, 'error');
|
||||
} finally {
|
||||
btn.disabled = false;
|
||||
btn.textContent = prev;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function esc(s) {
|
||||
const d = document.createElement('div');
|
||||
d.textContent = s ?? '';
|
||||
|
||||
Reference in New Issue
Block a user