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');