From 4925169ac9ab5b374d13713c23e2b88db3f5e354 Mon Sep 17 00:00:00 2001 From: cas Date: Fri, 24 Jul 2026 02:42:11 +0200 Subject: [PATCH] fix: event-delegatie voor meal-group acties (move/delete/toggle werken nu) + dialog-knoppen gebruiken bestaande Karby-classes (btn-cancel, btn-save, btn-danger-outline) + e2e test voor confirm modal --- docker/index.html | 61 ++++++++++++++++++----------------------------- index.html | 61 ++++++++++++++++++----------------------------- tests/e2e.spec.js | 44 ++++++++++++++++++++++++++++++++++ 3 files changed, 90 insertions(+), 76 deletions(-) diff --git a/docker/index.html b/docker/index.html index d0331cc..fc3cc97 100644 --- a/docker/index.html +++ b/docker/index.html @@ -2913,40 +2913,32 @@ button:active, .btn:active, .meal-card-main:active, .dagboek-item:active, .food- }); }); - // Meal group toggle collaps/expand - listEl.querySelectorAll('[data-action="toggle-meal"]').forEach(el => { - el.addEventListener('click', () => { - const group = el.closest('.eetmoment-meal-group'); + // === Unified meal-group action delegation === + listEl.addEventListener('click', (e) => { + const btn = e.target.closest('[data-action]'); + if (!btn) return; + const action = btn.dataset.action; + const momentId = btn.dataset.moment; + const entryIdx = btn.dataset.entry != null ? parseInt(btn.dataset.entry) : null; + + if (action === 'toggle-meal') { + const group = btn.closest('.eetmoment-meal-group'); if (!group) return; const wrap = group.querySelector('.eetmoment-meal-items-wrap'); const actions = group.querySelector('.eetmoment-meal-actions'); if (wrap) { wrap.classList.toggle('hidden'); if (actions) actions.classList.toggle('hidden'); - const arrow = el.querySelector('span:last-child i'); + const arrow = btn.querySelector('span:last-child i'); if (arrow) { arrow.className = wrap.classList.contains('hidden') ? 'fas fa-chevron-down' : 'fas fa-chevron-up'; } } - }); - }); - - // Meal group bulk edit button - listEl.querySelectorAll('[data-action="edit-porties"]').forEach(btn => { - btn.addEventListener('click', (e) => { - e.stopPropagation(); - const momentId = btn.dataset.moment; - const entryIdx = parseInt(btn.dataset.entry); + } + else if (action === 'edit-porties') { showBulkPortieEdit(activeDate, momentId, entryIdx); - }); - }); - - // Delete meal group from diary - listEl.querySelectorAll('[data-action="delete-meal"]').forEach(btn => { - btn.addEventListener('click', (e) => { - e.stopPropagation(); - const momentId = btn.dataset.moment; - const entryIdx = parseInt(btn.dataset.entry); + } + else if (action === 'delete-meal') { const dayData = getOrCreateDay(activeDate); const entry = (dayData[momentId] || [])[entryIdx]; const mealName = (entry && entry.mealNaam) || 'maaltijd'; @@ -2957,15 +2949,8 @@ button:active, .btn:active, .meal-card-main:active, .dagboek-item:active, .food- saveDagboek(); renderDagboek(); }); - }); - }); - - // Move meal group to different eetmoment - listEl.querySelectorAll('[data-action="move-meal"]').forEach(btn => { - btn.addEventListener('click', (e) => { - e.stopPropagation(); - const momentId = btn.dataset.moment; - const entryIdx = parseInt(btn.dataset.entry); + } + else if (action === 'move-meal') { const overlay = document.createElement('div'); overlay.className = 'modal-overlay'; overlay.style.zIndex = '500'; @@ -2979,8 +2964,8 @@ button:active, .btn:active, .meal-card-main:active, .dagboek-item:active, .food- @@ -3003,8 +2988,8 @@ button:active, .btn:active, .meal-card-main:active, .dagboek-item:active, .food- close(); renderDagboek(); }); - overlay.addEventListener('click', (e) => { if (e.target === overlay) close(); }); - }); + overlay.addEventListener('click', (ev) => { if (ev.target === overlay) close(); }); + } }); listEl.querySelectorAll('.eetmoment-add-btn').forEach(btn => { @@ -4255,8 +4240,8 @@ button:active, .btn:active, .meal-card-main:active, .dagboek-item:active, .food-

${escapeHtml(message)}

- - + +
`; diff --git a/index.html b/index.html index d0331cc..fc3cc97 100644 --- a/index.html +++ b/index.html @@ -2913,40 +2913,32 @@ button:active, .btn:active, .meal-card-main:active, .dagboek-item:active, .food- }); }); - // Meal group toggle collaps/expand - listEl.querySelectorAll('[data-action="toggle-meal"]').forEach(el => { - el.addEventListener('click', () => { - const group = el.closest('.eetmoment-meal-group'); + // === Unified meal-group action delegation === + listEl.addEventListener('click', (e) => { + const btn = e.target.closest('[data-action]'); + if (!btn) return; + const action = btn.dataset.action; + const momentId = btn.dataset.moment; + const entryIdx = btn.dataset.entry != null ? parseInt(btn.dataset.entry) : null; + + if (action === 'toggle-meal') { + const group = btn.closest('.eetmoment-meal-group'); if (!group) return; const wrap = group.querySelector('.eetmoment-meal-items-wrap'); const actions = group.querySelector('.eetmoment-meal-actions'); if (wrap) { wrap.classList.toggle('hidden'); if (actions) actions.classList.toggle('hidden'); - const arrow = el.querySelector('span:last-child i'); + const arrow = btn.querySelector('span:last-child i'); if (arrow) { arrow.className = wrap.classList.contains('hidden') ? 'fas fa-chevron-down' : 'fas fa-chevron-up'; } } - }); - }); - - // Meal group bulk edit button - listEl.querySelectorAll('[data-action="edit-porties"]').forEach(btn => { - btn.addEventListener('click', (e) => { - e.stopPropagation(); - const momentId = btn.dataset.moment; - const entryIdx = parseInt(btn.dataset.entry); + } + else if (action === 'edit-porties') { showBulkPortieEdit(activeDate, momentId, entryIdx); - }); - }); - - // Delete meal group from diary - listEl.querySelectorAll('[data-action="delete-meal"]').forEach(btn => { - btn.addEventListener('click', (e) => { - e.stopPropagation(); - const momentId = btn.dataset.moment; - const entryIdx = parseInt(btn.dataset.entry); + } + else if (action === 'delete-meal') { const dayData = getOrCreateDay(activeDate); const entry = (dayData[momentId] || [])[entryIdx]; const mealName = (entry && entry.mealNaam) || 'maaltijd'; @@ -2957,15 +2949,8 @@ button:active, .btn:active, .meal-card-main:active, .dagboek-item:active, .food- saveDagboek(); renderDagboek(); }); - }); - }); - - // Move meal group to different eetmoment - listEl.querySelectorAll('[data-action="move-meal"]').forEach(btn => { - btn.addEventListener('click', (e) => { - e.stopPropagation(); - const momentId = btn.dataset.moment; - const entryIdx = parseInt(btn.dataset.entry); + } + else if (action === 'move-meal') { const overlay = document.createElement('div'); overlay.className = 'modal-overlay'; overlay.style.zIndex = '500'; @@ -2979,8 +2964,8 @@ button:active, .btn:active, .meal-card-main:active, .dagboek-item:active, .food- @@ -3003,8 +2988,8 @@ button:active, .btn:active, .meal-card-main:active, .dagboek-item:active, .food- close(); renderDagboek(); }); - overlay.addEventListener('click', (e) => { if (e.target === overlay) close(); }); - }); + overlay.addEventListener('click', (ev) => { if (ev.target === overlay) close(); }); + } }); listEl.querySelectorAll('.eetmoment-add-btn').forEach(btn => { @@ -4255,8 +4240,8 @@ button:active, .btn:active, .meal-card-main:active, .dagboek-item:active, .food-

${escapeHtml(message)}

- - + +
`; diff --git a/tests/e2e.spec.js b/tests/e2e.spec.js index 1c94b91..426cef5 100644 --- a/tests/e2e.spec.js +++ b/tests/e2e.spec.js @@ -354,4 +354,48 @@ test.describe('Karby Eetdagboek', () => { await expect(chevronUp).toBeVisible(); }); + // ---------- Confirm + delete dialogs ---------- + + test('confirm modal: deletion dialog shows design-conforme buttons', async ({ page }) => { + await page.goto(BASE); + // Go to maaltijden tab + await page.locator('#navMaaltijden').click(); + await page.waitForTimeout(600); + // Quick-save a meal first if none exist (via search) + await page.locator('.search-input').fill('brood'); + await page.waitForTimeout(500); + await page.locator('.food-item').first().click(); + await page.waitForTimeout(500); + await page.locator('#detailAddBtn').click(); + await page.waitForTimeout(500); + await page.locator('#addMealSubmit').click(); + await page.waitForTimeout(600); + // Navigate to diary, save as meal + await page.locator('#navDagboek').click(); + await page.waitForTimeout(600); + const saveBtn = page.locator('.save-meal-btn'); + if (await saveBtn.count() === 0) { test.skip(); return; } + await saveBtn.first().click(); + await page.waitForTimeout(500); + await page.locator('#mealNameInput').fill('Test'); + await page.locator('#mealNameSave').click(); + await page.waitForTimeout(600); + // Now go to maaltijden and delete + await page.locator('#navMaaltijden').click(); + await page.waitForTimeout(600); + // Open first meal edit + await page.locator('.meal-card-main').first().click(); + await page.waitForTimeout(500); + // Click delete + const deleteBtn = page.locator('#mealEditDelete'); + if (await deleteBtn.isVisible().catch(() => false)) { + await deleteBtn.click(); + await page.waitForTimeout(300); + // Confirm modal should show + await expect(page.locator('#confirmOk')).toBeVisible({ timeout: 3000 }); + await expect(page.locator('#confirmCancel')).toBeVisible(); + await page.locator('#confirmCancel').click(); + } + }); + });