From bd9ab7304ec67f9e856b675d767daea0f6e9cbd2 Mon Sep 17 00:00:00 2001 From: "fefe.clochette" Date: Sat, 26 Sep 2026 10:01:27 +0200 Subject: [PATCH] Auto-commit for deploy to staging - 2026-09-26 10:01:27 --- includes/lang/ca.php | 1 + includes/lang/en.php | 2 +- includes/lang/fr.php | 1 + modules/food/views/meals.php | 73 ++++++++++++++++++++++++++++++++++++ 4 files changed, 76 insertions(+), 1 deletion(-) diff --git a/includes/lang/ca.php b/includes/lang/ca.php index 38f4698..450c0fc 100644 --- a/includes/lang/ca.php +++ b/includes/lang/ca.php @@ -1034,4 +1034,5 @@ return [ 'cta_food' => 'Cuinar', 'food_err_no_views' => "Cap vista activada per a aquest mòdul. Modifiqueu la vostra configuració d'espai.", 'food_err_no_views_desc' => 'Heu desactivat totes les funcions d\'aquest mòdul. Aneu a la configuració per reactivar-les.', + 'meal_paste_success' => 'Graella enganxada amb èxit!', ]; \ No newline at end of file diff --git a/includes/lang/en.php b/includes/lang/en.php index 259ad2f..1dcc13b 100644 --- a/includes/lang/en.php +++ b/includes/lang/en.php @@ -105,7 +105,6 @@ return [ 'mod_printvault_desc'=> 'Manage your 3D print files — STL, 3MF, GCode with interactive viewer.', 'mod_planka_name' => 'Planka', 'mod_planka_desc' => 'Manage your projects in Kanban mode with Planka.', - 'budget_mandatory_note' => 'Les onglets Suivi et Récapitulatif sont indispensables et toujours actifs.', 'cta_open' => 'Open', 'cta_explore' => 'Explore', @@ -1038,5 +1037,6 @@ return [ 'cta_food' => 'Cook up', 'food_err_no_views' => "No view is enabled for this module. Please check your space settings.", 'food_err_no_views_desc' => 'You have disabled all features for this module. Please visit your settings to re-enable them.', + 'meal_paste_success' => 'Grid pasted successfully!', ]; \ No newline at end of file diff --git a/includes/lang/fr.php b/includes/lang/fr.php index b15b0df..cd72334 100644 --- a/includes/lang/fr.php +++ b/includes/lang/fr.php @@ -1033,5 +1033,6 @@ return [ 'cta_food' => 'Mijoter', 'food_err_no_views' => "Aucune vue n'est activée pour ce module. Modifiez vos paramètres d'espace.", 'food_err_no_views_desc' => 'Vous avez désactivé toutes les fonctionnalités de ce module. Rendez-vous dans vos paramètres pour les réactiver.', + 'meal_paste_success' => 'Grille collée avec succès !', ]; \ No newline at end of file diff --git a/modules/food/views/meals.php b/modules/food/views/meals.php index b79a8b6..01ce696 100644 --- a/modules/food/views/meals.php +++ b/modules/food/views/meals.php @@ -407,4 +407,77 @@ window.importPdfMenu = async function(e) { updateDropzoneState(null); } }; + +// NOUVEAU : Interception du collage depuis Excel / Google Sheets +document.addEventListener('paste', async function(e) { + // On ne s'active que si on colle dans un textarea de repas + if (!e.target.classList.contains('js-meal-input')) return; + + const clipboardData = e.clipboardData || window.clipboardData; + const pastedText = clipboardData.getData('text/plain'); + + // Si le texte ne contient ni tabulation ni saut de ligne, c'est un collage simple. + // On laisse le navigateur faire son comportement par défaut. + if (!pastedText.includes('\t') && !pastedText.includes('\n')) return; + + // C'est une grille ! On bloque le comportement par défaut + e.preventDefault(); + + const rows = pastedText.split(/\r?\n/); + const startTd = e.target.closest('td'); + const startTr = e.target.closest('tr'); + const startColIndex = Array.from(startTr.children).indexOf(startTd); + + let currentTr = startTr; + let updates = []; + + for (let i = 0; i < rows.length; i++) { + if (!currentTr) break; // Fin du tableau visuel atteinte + + // Ignorer la dernière ligne vide souvent générée par les tableurs lors d'une copie + if (rows[i].trim() === '' && i === rows.length - 1) continue; + + const cells = rows[i].split('\t'); + const trChildren = Array.from(currentTr.children); + + for (let j = 0; j < cells.length; j++) { + const targetTd = trChildren[startColIndex + j]; + if (!targetTd) continue; // Fin de la colonne visuelle atteinte + + const targetTextarea = targetTd.querySelector('.js-meal-input'); + if (targetTextarea) { + const val = cells[j].trim(); + targetTextarea.value = val; + + // Animation de succès visuel + if (typeof flashSuccess === 'function') flashSuccess(targetTextarea); + + // Préparation pour le Bulk Save + updates.push({ + plan_date: targetTextarea.dataset.d, + service: targetTextarea.dataset.s, + person_id: targetTextarea.dataset.p, + meal_name: val + }); + } + } + // Descendre d'une ligne dans le tableau (ex: passer de Midi à Soir, ou de Soir au Midi du lendemain) + currentTr = currentTr.nextElementSibling; + } + + // Sauvegarde groupée optimisée + if (updates.length > 0) { + const fd = new FormData(); + fd.append('action', 'save_bulk'); + fd.append('updates', JSON.stringify(updates)); + + try { + await pachaFetch('/modules/food/includes/api/save-meals.php', { method: 'POST', body: fd }); + if (window.showToast) showToast(window.I18N['meal_paste_success'] || 'Grille collée avec succès !', 'success'); + } catch(err) { + console.error("Erreur de sauvegarde lors du collage", err); + if (window.showToast) showToast(window.I18N['error_occured'], 'error'); + } + } +}); \ No newline at end of file