refactored confirmation dialogs to use a unified confirmAction modal
Some checks failed
PHPUnit / test (push) Has been cancelled

This commit is contained in:
2026-06-14 18:02:03 +02:00
parent 6ae29f1648
commit b06c4bf3ee
10 changed files with 295 additions and 39 deletions

View File

@ -1,5 +1,6 @@
import { apiGet, apiPost, apiPut, apiDelete } from '../api.js';
import { canEdit, pageHeaderHTML, showToast, getRole } from '../app.js';
import { confirmAction } from '../confirm-modal.js';
import { navigate } from '../router.js';
export async function questionnairesPage() {
@ -111,7 +112,12 @@ function renderCategoryKeysPanel(categoryKeys) {
if (count > 0) {
msg += `\n\n${count} questionnaire(s) will have their category key cleared.`;
}
if (!confirm(msg)) return;
if (!(await confirmAction({
title: 'Delete category key',
message: msg,
confirmLabel: 'Delete',
variant: 'danger',
}))) return;
btn.disabled = true;
try {
const result = await apiPost('questionnaires.php', { action: 'deleteCategoryKey', categoryKey: key });
@ -297,7 +303,12 @@ function renderGrid(questionnaires, categoryKeys = []) {
grid.querySelectorAll('.delete-q-btn').forEach(btn => {
btn.addEventListener('click', async (e) => {
e.stopPropagation();
if (!confirm('Delete this questionnaire and all its data?')) return;
if (!(await confirmAction({
title: 'Delete questionnaire',
message: 'Delete this questionnaire and all its data?',
confirmLabel: 'Delete',
variant: 'danger',
}))) return;
try {
await apiDelete('questionnaires.php', { questionnaireID: btn.dataset.id });
showToast('Questionnaire deleted', 'success');
@ -491,7 +502,12 @@ function renderScoringProfilesSection(profiles, questionnaires) {
});
list.querySelectorAll('.delete-profile-btn').forEach(btn => {
btn.addEventListener('click', async () => {
if (!confirm(`Delete scoring profile "${btn.dataset.name}"?`)) return;
if (!(await confirmAction({
title: 'Delete scoring profile',
message: `Delete scoring profile "${btn.dataset.name}"?`,
confirmLabel: 'Delete',
variant: 'danger',
}))) return;
try {
await apiDelete('scoring_profiles.php', { profileID: btn.dataset.id });
showToast('Profile deleted', 'success');
@ -761,12 +777,32 @@ function bindImportBundle() {
}
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)'
);
if (!(await confirmAction({
title: 'Import questionnaires',
message: `Import ${count} questionnaire(s) from this file?`,
confirmLabel: 'Import',
}))) return;
const mode = await confirmAction({
title: 'Existing questionnaire IDs',
message: 'If a questionnaire ID from the file already exists, how should it be handled?',
choices: [
{
value: 'replace',
label: 'Replace existing',
description: 'Overwrite the questionnaire with that ID.',
},
{
value: 'copy',
label: 'Import as new copy',
description: 'Keep the existing questionnaire and import with a new ID.',
},
],
confirmLabel: 'Continue',
cancelLabel: 'Cancel import',
});
if (!mode) return;
const replace = mode === 'replace';
btn.disabled = true;
const prev = btn.textContent;