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 = '
'
+ + '
' + icon + '
'
+ + '
' + 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');