MSIN-4546 — Implement production panel loading via AJAX on first click, enhancing user experience by deferring content loading until necessary. Update version code to 4.72.938.

This commit is contained in:
2026-08-03 11:41:00 -04:00
parent 32b66a1375
commit 589c788b97
4 changed files with 117 additions and 7 deletions

View File

@ -53,6 +53,7 @@ $arrBibAjaxActions = [
'production_fields_save',
'qty_summary',
'race_detail',
'production_panel',
];
if ($action !== '' && in_array($action, $arrBibAjaxActions, true)) {
@ -1316,6 +1317,37 @@ if ($action == 'anomalies') {
exit;
}
// MSIN-4546 — Onglet Production (chargé seulement à l'ouverture de l'espace).
if ($action == 'production_panel') {
$int_eve_id = (int)($_POST['eve_id'] ?? $_GET['eve_id'] ?? 0);
if ($int_eve_id <= 0) {
echo json_encode([
'success' => false,
'message' => fxBibMsg('bib_v4_ajax_epr_invalid'),
]);
exit;
}
global $objDatabase;
$tabEpreuves = $objDatabase->fxGetResults(
"SELECT * FROM inscriptions_epreuves e
WHERE e.eve_id = $int_eve_id AND e.epr_actif = 1
ORDER BY e.epr_id"
);
if (!is_array($tabEpreuves)) {
$tabEpreuves = [];
}
$tabShellStats = fxBibCollectEventShellStats($int_eve_id);
echo json_encode([
'success' => true,
'html' => renderBibProductionPreview($tabEpreuves, $strLangue, $tabShellStats),
]);
exit;
}
// MSIN-4546 — Détail éditable d'une épreuve (ouverture carte).
if ($action == 'race_detail') {

View File

@ -593,6 +593,11 @@
bibSyncWorkspaceTabHighlight();
bibSyncWorkspaceSurfaceVisibility();
// MSIN-4546 — Charger Production seulement quand on ouvre cet espace.
if (workspaceId === 'production') {
bibEnsureProductionPanelLoaded();
}
// MSIN-4475 — Modes d'assignation : afficher les choix tout de suite (sans clic tuile).
if (workspaceId === 'operations' && options.keepTool !== true) {
var autoTool = panel.getAttribute('data-bib-auto-tool');
@ -602,6 +607,60 @@
}
}
var bibProductionLoadPromise = null;
/**
* MSIN-4546 — Onglet Production = page séparée : AJAX au 1er clic seulement.
*/
function bibEnsureProductionPanelLoaded() {
var panel = moduleBib.querySelector('[data-bib-workspace-panel="production"]');
var mount = document.getElementById('bib-production-mount');
if (!panel) {
return Promise.resolve();
}
// Déjà chargé (mount remplacé par le HTML production).
if (panel.getAttribute('data-production-loaded') === '1' || !mount) {
return Promise.resolve();
}
if (panel.getAttribute('data-production-deferred') !== '1'
&& mount.getAttribute('data-production-deferred') !== '1') {
return Promise.resolve();
}
if (bibProductionLoadPromise) {
return bibProductionLoadPromise;
}
bibProductionLoadPromise = bibFetch('/ajax_bib_range.php', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: 'action=production_panel'
+ '&eve_id=' + encodeURIComponent(moduleBib.dataset.eveId || '')
+ bibAjaxLangSuffix()
}, { loader: true })
.then(function (res) { return res.json(); })
.then(function (data) {
if (!data || !data.success || !data.html) {
throw new Error((data && data.message) || bibJs('jsErrGeneric') || 'Erreur');
}
mount.outerHTML = data.html;
panel.removeAttribute('data-production-deferred');
panel.setAttribute('data-production-loaded', '1');
initModuleBibTippy(panel);
return panel;
})
.catch(function (err) {
var msg = (err && err.message) ? err.message : (bibJs('jsServerError') || 'Erreur serveur');
mount.innerHTML = '<div class="text-danger small" style="padding:12px;">'
+ bibTippyEscapeHtml(msg)
+ '</div>';
})
.finally(function () {
bibProductionLoadPromise = null;
});
return bibProductionLoadPromise;
}
/** MSIN-4512 — PDF ouvert : ne pas laisser longlet workspace allumé en parallèle. */
function bibSyncWorkspaceTabHighlight() {
var highlightWorkspace = (bibActiveTool === 'dist_print') ? null : bibActiveWorkspace;

View File

@ -5454,6 +5454,25 @@ function renderBibProductionFieldSideRow($intEprId, $strKey, $strLabel, $strSele
}
/** MSIN-4467 / MSIN-4469 / MSIN-4515 — Production physique et fichier officiel Excel. */
/**
* MSIN-4546 — Coquille onglet Production (aucun catalogue Face/Endos au 1er paint).
*/
function renderBibProductionPreviewShell($intEveId, $strLangue = 'fr') {
$intEveId = (int)$intEveId;
ob_start();
?>
<div id="bib-production-mount"
class="bib-production-mount"
data-eve-id="<?php echo $intEveId; ?>"
data-production-deferred="1">
<div class="bib-workspace-panel-heading">
<p class="text-muted small mb-0"><?php echo fxBibEsc(fxBibTexte('bib_v4_js_loader_wait', 0)); ?></p>
</div>
</div>
<?php
return ob_get_clean();
}
function renderBibProductionPreview(array $tabEpreuves, $strLangue = 'fr', array $tabShellStats = null) {
global $vDomaine, $objDatabase;
@ -5762,12 +5781,12 @@ function renderBibToolNav($int_eve_id, $tabEpreuves, $strLangue = 'fr', array $t
<section class="bib-workspace-panel bib-ui-hidden"
data-bib-workspace-panel="production"
data-production-deferred="1">
<?php // MSIN-4546 — Preview production différée (champs Face/Endos × N épreuves = ~12s sinon). ?>
<div id="bib-production-mount">
<div class="bib-production-placeholder text-muted small" style="padding:12px;">
<?php echo fxBibEsc(fxBibTexte('bib_v4_js_loader_wait', 0)); ?>
</div>
</div>
<?php
// MSIN-4546 — Production = autre page : pas de catalogue Face/Endos au 1er paint.
fxBibTimingMark('toolnav: before production shell');
echo renderBibProductionPreviewShell((int)$int_eve_id, $strLangue);
fxBibTimingMark('toolnav: after production shell');
?>
</section>
<?php

View File

@ -7,7 +7,7 @@
* Constantes *
*
**************/
define('_VERSION_CODE', '4.72.937'); // MSIN-4546 — timing bib toujours on en env dev
define('_VERSION_CODE', '4.72.938'); // MSIN-4546 — Production différée (onglet = page)
define('_DATE_CODE', '2026-08-03');
//MSIN-4290
define('QR_SECRET_KEY', 'ms1_qr_2026_cle_secrete_longue_et_fixe');