From 33706bb1950d17fda3f3f1cbda1402293b9129f1 Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 9 Jul 2026 12:48:02 -0400 Subject: [PATCH] Implement global batch completion UI, enhance JavaScript handling, and increment version code to 4.72.784 This commit introduces a new user interface for displaying the completion status of global batch assignments, including success, warning, and error states. The CSS is updated to style the completion messages appropriately. Additionally, JavaScript functions are added to manage the display of these messages based on assignment results. Localization keys are also added for improved user feedback. The version code is incremented to 4.72.784 to reflect these changes. --- css/style.css | 48 +++++ js/v2/bib-assignments.js | 180 ++++++++++--------- php/inc_fx_promoteur.php | 8 + php/inc_settings.php | 2 +- sql/MSIN-4443-bib-global-batch-generated.sql | 32 ++++ 5 files changed, 187 insertions(+), 83 deletions(-) diff --git a/css/style.css b/css/style.css index 1128dea..0f4f378 100644 --- a/css/style.css +++ b/css/style.css @@ -1524,6 +1524,54 @@ ul.ms1-menu-compte li a:hover, ul.ms1-menu-compte li a:active { margin-bottom:8px; } +/* MSIN-4443 — Écran de fin assignation globale GO */ +.bib-global-batch-complete{ + margin:0; + padding:28px 24px 32px; + text-align:center; + background:#fff; + border:1px solid #c5d9f5; + border-radius:10px; + box-shadow:0 4px 18px rgba(47,95,208,.08); +} +.bib-global-batch-complete--ok{ + border-color:#9fd4b0; + background:linear-gradient(180deg,#f3fbf5 0%,#fff 55%); +} +.bib-global-batch-complete--warning{ + border-color:#f0d58a; + background:linear-gradient(180deg,#fffbf0 0%,#fff 55%); +} +.bib-global-batch-complete--error{ + border-color:#efb8b8; + background:linear-gradient(180deg,#fff5f5 0%,#fff 55%); +} +.bib-global-batch-complete__icon{ + font-size:2.5rem; + line-height:1; + margin-bottom:12px; +} +.bib-global-batch-complete__title{ + font-size:1.35rem; + font-weight:700; + margin:0 0 10px; + color:#1a3a6b; +} +.bib-global-batch-complete__message{ + font-size:1.05rem; + margin:0 0 8px; + color:#333; +} +.bib-global-batch-complete__summary{ + font-size:.95rem; + color:#5a6c7d; + margin:0 0 24px; +} +.bib-global-batch-complete__reload{ + min-width:220px; + font-weight:600; +} + /* Typographie cohérente — module bib v4 */ #module-bib .epr-header{ font-size:15px; diff --git a/js/v2/bib-assignments.js b/js/v2/bib-assignments.js index 4004d8f..f670751 100644 --- a/js/v2/bib-assignments.js +++ b/js/v2/bib-assignments.js @@ -386,6 +386,82 @@ } } + function bibEscHtml(str) { + return String(str == null ? '' : str) + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"'); + } + + function bibFinishGlobalBatchGo(runResults) { + var totalAssigned = 0; + var totalExpected = 0; + var nbEpreuves = runResults ? runResults.length : 0; + + (runResults || []).forEach(function (result) { + totalAssigned += result.assigned || 0; + totalExpected += result.total || 0; + }); + + var remaining = Math.max(0, totalExpected - totalAssigned); + var state = 'ok'; + var icon = '\u2713'; + var title = bibJs('jsGlobalBatchCompleteTitle') || 'Assignation terminée'; + var message = ''; + var summary = bibJsFmt( + 'jsGlobalBatchCompleteSummary', + totalAssigned, + totalExpected, + nbEpreuves + ); + + if (totalAssigned === 0 && totalExpected > 0) { + state = 'error'; + icon = '!'; + message = bibJs('jsAssignNone') || bibJs('jsErrGeneric'); + } else if (remaining > 0) { + state = 'warning'; + icon = '!'; + message = bibJsFmt('jsAssignPartial', totalAssigned, remaining); + } else if (totalAssigned > 0) { + message = bibJsFmt('jsAssignFull', totalAssigned); + } else { + state = 'error'; + icon = '!'; + message = bibJs('jsErrGeneric'); + } + + bibBatchProgressForceHide(); + bibRemoveGlobalSimViews(); + + var reloadLabel = bibJs('jsGlobalBatchCompleteReload') || 'OK'; + var html = '
' + + '' + + '

' + bibEscHtml(title) + '

' + + '

' + bibEscHtml(message) + '

' + + '

' + bibEscHtml(summary) + '

' + + '' + + '
'; + + var detailBody = document.getElementById('bib-tool-detail-body'); + if (detailBody) { + detailBody.innerHTML = html; + var detail = document.getElementById('bib-tool-detail'); + if (detail) { + detail.classList.remove('bib-ui-hidden'); + detail.scrollIntoView({ behavior: 'smooth', block: 'start' }); + } + return; + } + + location.reload(); + } + function bibRemoveGlobalSimViews() { document.querySelectorAll('.bib-global-sim-view').forEach(function (el) { el.remove(); @@ -1054,7 +1130,11 @@ }); return chain.then(function () { - bibBatchProgressShow(globalTotal, globalTotal); + bibBatchProgressShow( + globalTotal, + globalTotal, + bibJs('jsGlobalBatchFinalizing') || bibJs('jsLoaderWait') + ); var refreshChain = Promise.resolve(); runResults.forEach(function (result) { @@ -1072,56 +1152,10 @@ return refreshChain.then(function () { if (typeof refreshBibAnomaliesPanel === 'function') { - refreshBibAnomaliesPanel(); + return refreshBibAnomaliesPanel(); } - - var totalAssigned = 0; - var totalExpected = 0; - - runResults.forEach(function (result) { - totalAssigned += result.assigned; - totalExpected += result.total; - }); - - var remaining = Math.max(0, totalExpected - totalAssigned); - - bibInvalidateGlobalBatchPanel(); - return bibEnsureGlobalBatchPanelLoaded().then(function () { - if (bibActiveTool === 'global_batch') { - bibInvalidateToolSlot('global_batch'); - bibMountToolContent('global_batch'); - initModuleBibTippy(document.getElementById('bib-tool-detail')); - } - - return Promise.all([ - updateGlobalBatchAnalysis(), - updateGlobalBatchGeneratedAnalysis() - ]).then(function () { - var genSection = bibGetGlobalBatchGeneratedSection(); - var infoEl = genSection - ? genSection.querySelector('.bib-global-gen-batch__info') - : null; - - if (totalAssigned === 0 && totalExpected > 0) { - var msgNone = bibJs('jsAssignNone') || bibJs('jsErrGeneric'); - if (infoEl) { - bibSetGlobalBatchInfo(infoEl, msgNone, 'error'); - } - alert(msgNone); - } else if (remaining > 0) { - var msgPartial = bibJsFmt('jsAssignPartial', totalAssigned, remaining); - if (infoEl) { - bibSetGlobalBatchInfo(infoEl, msgPartial, 'warning'); - } - alert(msgPartial); - } else if (totalAssigned > 0) { - var msgFull = bibJsFmt('jsAssignFull', totalAssigned); - if (infoEl) { - bibSetGlobalBatchInfo(infoEl, msgFull, 'ok'); - } - } - }); - }); + }).then(function () { + bibFinishGlobalBatchGo(runResults); }); }); }) @@ -1213,7 +1247,11 @@ }); return chain.then(function () { - bibBatchProgressShow(globalTotal, globalTotal); + bibBatchProgressShow( + globalTotal, + globalTotal, + bibJs('jsGlobalBatchFinalizing') || bibJs('jsLoaderWait') + ); var refreshChain = Promise.resolve(); runResults.forEach(function (result) { @@ -1231,38 +1269,10 @@ return refreshChain.then(function () { if (typeof refreshBibAnomaliesPanel === 'function') { - refreshBibAnomaliesPanel(); + return refreshBibAnomaliesPanel(); } - - var panelRef = bibGetGlobalBatchExistingSection(); - var infoEl = panelRef ? panelRef.querySelector('.bib-global-batch__info') : null; - var totalAssigned = 0; - var totalExpected = 0; - - runResults.forEach(function (result) { - totalAssigned += result.assigned; - totalExpected += result.total; - }); - - var remaining = Math.max(0, totalExpected - totalAssigned); - - return updateGlobalBatchAnalysis().then(function () { - if (totalAssigned === 0 && totalExpected > 0) { - var msgNone = bibJs('jsAssignNone') || bibJs('jsErrGeneric'); - bibSetGlobalBatchInfo(infoEl, msgNone, 'error'); - alert(msgNone); - } else if (remaining > 0) { - var msgPartial = bibJsFmt('jsAssignPartial', totalAssigned, remaining); - bibSetGlobalBatchInfo(infoEl, msgPartial, 'warning'); - alert(msgPartial); - } else if (totalAssigned > 0) { - bibSetGlobalBatchInfo( - infoEl, - bibJsFmt('jsAssignFull', totalAssigned), - 'ok' - ); - } - }); + }).then(function () { + bibFinishGlobalBatchGo(runResults); }); }); }) @@ -1287,6 +1297,12 @@ }); moduleBib.addEventListener('click', function (e) { + if (e.target.closest('.btn-global-batch-complete-reload')) { + e.preventDefault(); + location.reload(); + return; + } + if (e.target.closest('.bib-tool-detail__close')) { e.preventDefault(); bibCloseTool(); diff --git a/php/inc_fx_promoteur.php b/php/inc_fx_promoteur.php index 619db9d..59eb0d4 100644 --- a/php/inc_fx_promoteur.php +++ b/php/inc_fx_promoteur.php @@ -3334,6 +3334,10 @@ function fxBibStaticFallback($clef) { 'bib_v4_global_batch_unavailable' => ['fr' => 'Aucune assignation globale disponible pour cet événement.', 'en' => 'No global assignment available for this event.'], 'bib_v4_ajax_global_gen_sim_summary' => ['fr' => '%d épreuve(s) · %d dossards · %d à assigner', 'en' => '%d race(s) · %d bibs · %d to assign'], 'bib_v4_ajax_global_gen_analysis' => ['fr' => '%d épreuve(s) · plage %d → %d · %d à assigner', 'en' => '%d race(s) · range %d → %d · %d to assign'], + 'bib_v4_js_global_batch_finalizing' => ['fr' => 'Finalisation — mise à jour de l\'affichage…', 'en' => 'Finishing — refreshing the display…'], + 'bib_v4_global_batch_go_complete_title' => ['fr' => 'Assignation terminée', 'en' => 'Assignment complete'], + 'bib_v4_global_batch_go_complete_summary' => ['fr' => '%d dossard(s) assigné(s) sur %d · %d épreuve(s)', 'en' => '%d bib(s) assigned of %d · %d race(s)'], + 'bib_v4_global_batch_go_complete_reload' => ['fr' => 'OK — Recharger la page', 'en' => 'OK — Reload page'], 'bib_v4_batch_order_2' => ['fr' => 'Tri secondaire', 'en' => 'Secondary sort'], 'bib_v4_batch_order_none' => ['fr' => '— Aucun —', 'en' => '— None —'], 'bib_v4_batch_sort_group_fixed' => ['fr' => 'Critères fixes', 'en' => 'Fixed criteria'], @@ -3586,6 +3590,10 @@ function fxBibModuleJsDataAttrs() { 'global-no-seq' => 'bib_v4_js_global_no_seq', 'global-gen-no-start' => 'bib_v4_global_batch_gen_no_start', 'global-gen-no-epr' => 'bib_v4_js_global_no_epr', + 'global-batch-finalizing' => 'bib_v4_js_global_batch_finalizing', + 'global-batch-complete-title' => 'bib_v4_global_batch_go_complete_title', + 'global-batch-complete-summary' => 'bib_v4_global_batch_go_complete_summary', + 'global-batch-complete-reload' => 'bib_v4_global_batch_go_complete_reload', 'reset-all-confirm' => 'bib_v4_js_reset_all_confirm', 'reset-all-locked' => 'bib_v4_js_reset_all_locked', 'assign-full' => 'bib_v4_ajax_assign_full', diff --git a/php/inc_settings.php b/php/inc_settings.php index 7523626..895cf57 100644 --- a/php/inc_settings.php +++ b/php/inc_settings.php @@ -7,7 +7,7 @@ * Constantes * * **************/ -define('_VERSION_CODE', '4.72.783'); +define('_VERSION_CODE', '4.72.784'); define('_DATE_CODE', '2026-07-09'); //MSIN-4290 define('QR_SECRET_KEY', 'ms1_qr_2026_cle_secrete_longue_et_fixe'); diff --git a/sql/MSIN-4443-bib-global-batch-generated.sql b/sql/MSIN-4443-bib-global-batch-generated.sql index d59fe47..462fc60 100644 --- a/sql/MSIN-4443-bib-global-batch-generated.sql +++ b/sql/MSIN-4443-bib-global-batch-generated.sql @@ -96,3 +96,35 @@ FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM info WHERE info_clef = 'bib_v4_ajax_gl INSERT INTO info (info_clef, info_langue, info_texte, info_aide, info_prg, info_description, info_trie, info_actif, info_option1, info_option2, info_option3, info_creation) SELECT 'bib_v4_ajax_global_gen_analysis', 'en', '%d race(s) · range %d → %d · %d to assign', '', 'compte.php', '', 0, 1, '', '', '', NOW() FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM info WHERE info_clef = 'bib_v4_ajax_global_gen_analysis' AND info_langue = 'en' AND info_prg = 'compte.php'); + +INSERT INTO info (info_clef, info_langue, info_texte, info_aide, info_prg, info_description, info_trie, info_actif, info_option1, info_option2, info_option3, info_creation) +SELECT 'bib_v4_js_global_batch_finalizing', 'fr', 'Finalisation — mise à jour de l''affichage…', '', 'compte.php', '', 0, 1, '', '', '', NOW() +FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM info WHERE info_clef = 'bib_v4_js_global_batch_finalizing' AND info_langue = 'fr' AND info_prg = 'compte.php'); + +INSERT INTO info (info_clef, info_langue, info_texte, info_aide, info_prg, info_description, info_trie, info_actif, info_option1, info_option2, info_option3, info_creation) +SELECT 'bib_v4_js_global_batch_finalizing', 'en', 'Finishing — refreshing the display…', '', 'compte.php', '', 0, 1, '', '', '', NOW() +FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM info WHERE info_clef = 'bib_v4_js_global_batch_finalizing' AND info_langue = 'en' AND info_prg = 'compte.php'); + +INSERT INTO info (info_clef, info_langue, info_texte, info_aide, info_prg, info_description, info_trie, info_actif, info_option1, info_option2, info_option3, info_creation) +SELECT 'bib_v4_global_batch_go_complete_title', 'fr', 'Assignation terminée', '', 'compte.php', '', 0, 1, '', '', '', NOW() +FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM info WHERE info_clef = 'bib_v4_global_batch_go_complete_title' AND info_langue = 'fr' AND info_prg = 'compte.php'); + +INSERT INTO info (info_clef, info_langue, info_texte, info_aide, info_prg, info_description, info_trie, info_actif, info_option1, info_option2, info_option3, info_creation) +SELECT 'bib_v4_global_batch_go_complete_title', 'en', 'Assignment complete', '', 'compte.php', '', 0, 1, '', '', '', NOW() +FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM info WHERE info_clef = 'bib_v4_global_batch_go_complete_title' AND info_langue = 'en' AND info_prg = 'compte.php'); + +INSERT INTO info (info_clef, info_langue, info_texte, info_aide, info_prg, info_description, info_trie, info_actif, info_option1, info_option2, info_option3, info_creation) +SELECT 'bib_v4_global_batch_go_complete_summary', 'fr', '%d dossard(s) assigné(s) sur %d · %d épreuve(s)', '', 'compte.php', '', 0, 1, '', '', '', NOW() +FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM info WHERE info_clef = 'bib_v4_global_batch_go_complete_summary' AND info_langue = 'fr' AND info_prg = 'compte.php'); + +INSERT INTO info (info_clef, info_langue, info_texte, info_aide, info_prg, info_description, info_trie, info_actif, info_option1, info_option2, info_option3, info_creation) +SELECT 'bib_v4_global_batch_go_complete_summary', 'en', '%d bib(s) assigned of %d · %d race(s)', '', 'compte.php', '', 0, 1, '', '', '', NOW() +FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM info WHERE info_clef = 'bib_v4_global_batch_go_complete_summary' AND info_langue = 'en' AND info_prg = 'compte.php'); + +INSERT INTO info (info_clef, info_langue, info_texte, info_aide, info_prg, info_description, info_trie, info_actif, info_option1, info_option2, info_option3, info_creation) +SELECT 'bib_v4_global_batch_go_complete_reload', 'fr', 'OK — Recharger la page', '', 'compte.php', '', 0, 1, '', '', '', NOW() +FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM info WHERE info_clef = 'bib_v4_global_batch_go_complete_reload' AND info_langue = 'fr' AND info_prg = 'compte.php'); + +INSERT INTO info (info_clef, info_langue, info_texte, info_aide, info_prg, info_description, info_trie, info_actif, info_option1, info_option2, info_option3, info_creation) +SELECT 'bib_v4_global_batch_go_complete_reload', 'en', 'OK — Reload page', '', 'compte.php', '', 0, 1, '', '', '', NOW() +FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM info WHERE info_clef = 'bib_v4_global_batch_go_complete_reload' AND info_langue = 'en' AND info_prg = 'compte.php');