MSIN-4467 — Enhance bib management workspace with new grouping for quantities and bibs, update CSS for improved layout and styling, and increment version code to 4.72.844.

This commit is contained in:
2026-07-21 11:27:23 -04:00
parent 2d86789938
commit 397d82a458
6 changed files with 166 additions and 62 deletions

View File

@ -1145,9 +1145,37 @@ ul.ms1-menu-compte li a:hover, ul.ms1-menu-compte li a:active {
margin-bottom:16px;
}
#module-bib .bib-preparation-groups{
display:grid;
grid-template-columns:repeat(2, minmax(0, 1fr));
gap:12px;
}
#module-bib .bib-preparation-group{
display:flex;
flex-direction:column;
gap:10px;
min-width:0;
padding:12px;
border:1px solid #c8d6e5;
border-radius:8px;
background:#f8fbfe;
}
#module-bib .bib-preparation-group--quantities{
background:#fafbfc;
}
#module-bib .bib-preparation-group h3{
margin:0;
color:#1e3a6e;
font-size:14px;
font-weight:700;
}
#module-bib .bib-preparation-stats{
display:grid;
grid-template-columns:repeat(4, minmax(0, 1fr));
grid-template-columns:repeat(2, minmax(0, 1fr));
gap:1px;
margin:0;
overflow:hidden;
@ -1201,9 +1229,9 @@ ul.ms1-menu-compte li a:hover, ul.ms1-menu-compte li a:active {
gap:8px;
}
#module-bib .bib-tool-nav--preparation,
#module-bib .bib-tool-nav--operations{
grid-template-columns:repeat(2, minmax(0, 1fr));
grid-template-columns:minmax(0, 1fr);
max-width:520px;
}
#module-bib .bib-tool-nav--settings{
@ -1211,6 +1239,15 @@ ul.ms1-menu-compte li a:hover, ul.ms1-menu-compte li a:active {
max-width:520px;
}
#module-bib .bib-tool-nav--group{
grid-template-columns:minmax(0, 1fr);
margin-top:auto;
}
#module-bib .bib-tool-nav--group-bibs{
grid-template-columns:repeat(2, minmax(0, 1fr));
}
#module-bib .bib-tool-btn:nth-child(4){
grid-column:1;
}
@ -1631,6 +1668,10 @@ ul.ms1-menu-compte li a:hover, ul.ms1-menu-compte li a:active {
flex:1 0 auto;
}
#module-bib .bib-preparation-groups{
grid-template-columns:1fr;
}
#module-bib .bib-preparation-stats{
grid-template-columns:repeat(2, minmax(0, 1fr));
}
@ -1961,7 +2002,7 @@ ul.ms1-menu-compte li a:hover, ul.ms1-menu-compte li a:active {
.bib-race-summary{
display:grid;
grid-template-columns:minmax(220px, 1.4fr) minmax(300px, 1.4fr) auto 32px;
grid-template-columns:minmax(220px, 1.2fr) minmax(180px, .9fr) minmax(270px, 1.3fr) 32px;
gap:14px;
align-items:center;
min-height:64px;
@ -2001,6 +2042,21 @@ ul.ms1-menu-compte li a:hover, ul.ms1-menu-compte li a:active {
white-space:nowrap;
}
.bib-race-summary__group{
min-width:0;
padding-left:12px;
border-left:1px solid #dbe4f3;
}
.bib-race-summary__group h4{
margin:0 0 5px;
color:#6c757d;
font-size:10px;
font-weight:700;
letter-spacing:.03em;
text-transform:uppercase;
}
.bib-race-summary__stats{
display:grid;
grid-template-columns:repeat(3, minmax(0, 1fr));
@ -2008,6 +2064,10 @@ ul.ms1-menu-compte li a:hover, ul.ms1-menu-compte li a:active {
margin:0;
}
.bib-race-summary__group--quantities .bib-race-summary__stats{
grid-template-columns:repeat(2, minmax(0, 1fr));
}
.bib-race-summary__stats > div{
min-width:0;
}
@ -3326,15 +3386,19 @@ a.ms1-trad-link.btn-aide-trad{
grid-template-columns:minmax(0, 1fr) auto;
}
.bib-race-summary__stats{
.bib-race-summary__group{
grid-column:1 / -1;
padding:8px 0 0;
border-top:1px solid #dbe4f3;
border-left:0;
}
.bib-race-summary__group--quantities{
grid-row:2;
}
.bib-race-summary__status{
grid-column:1;
.bib-race-summary__group--bibs{
grid-row:3;
justify-self:start;
}
.bib-race-toggle{

View File

@ -540,7 +540,7 @@
if (toolId === 'event_config') {
return 'settings';
}
if (toolId === 'anomalies' || toolId === 'dist_print') {
if (toolId === 'global_batch') {
return 'operations';
}
return 'preparation';
@ -2219,17 +2219,6 @@
function bibSyncRaceSummaryStatus(row) {
if (!row) return;
var pendingEl = row.querySelector('.bib-race-summary-pending');
var rangesEl = row.querySelector('.bib-race-summary-ranges');
var statusEl = row.querySelector('.bib-race-summary__status');
var pending = parseInt(pendingEl ? pendingEl.textContent : '0', 10) || 0;
var ranges = parseInt(rangesEl ? rangesEl.textContent : '0', 10) || 0;
var ready = pending === 0 && ranges > 0;
if (statusEl) {
statusEl.classList.toggle('is-ready', ready);
statusEl.textContent = statusEl.getAttribute(ready ? 'data-label-ready' : 'data-label-incomplete') || '';
}
bibRefreshPreparationOverview();
}
@ -2315,6 +2304,12 @@
if (elRestante) {
elRestante.value = row.qte_restante;
}
let summaryAvailable = document.querySelector(
'.epr-row[data-epr-id="' + eprId + '"] .bib-race-summary-available'
);
if (summaryAvailable && row.qte_restante !== undefined) {
summaryAvailable.textContent = row.qte_restante;
}
let dispoBadge = document.querySelector(
'.epr-row[data-epr-id="' + eprId + '"] .epr-header-summary--dispo'

View File

@ -3566,6 +3566,9 @@ function fxBibStaticFallback($clef) {
'bib_v5_workspace_operations' => ['fr' => 'Opérations', 'en' => 'Operations'],
'bib_v5_workspace_settings' => ['fr' => 'Réglages', 'en' => 'Settings'],
'bib_v5_preparation_intro' => ['fr' => 'Préparez les épreuves et attribuez les dossards aux inscriptions.', 'en' => 'Prepare races and assign bibs to registrations.'],
'bib_v5_group_quantities' => ['fr' => 'Quantités', 'en' => 'Quantities'],
'bib_v5_group_bibs' => ['fr' => 'Dossards', 'en' => 'Bibs'],
'bib_v5_modes_intro' => ['fr' => 'Utilisez les modes dassignation qui traitent plusieurs épreuves ou des besoins particuliers.', 'en' => 'Use assignment modes that process multiple races or special requirements.'],
'bib_v5_stat_races' => ['fr' => 'Épreuves actives', 'en' => 'Active races'],
'bib_v5_stat_registered' => ['fr' => 'Inscriptions', 'en' => 'Registrations'],
'bib_v5_stat_assigned' => ['fr' => 'Dossards attribués', 'en' => 'Assigned bibs'],
@ -4813,7 +4816,7 @@ function renderBibWorkspaceTab($strWorkspace, $strTitleClef, $blnActive = false)
}
/** MSIN-4467 — Résumé événement affiché avant le détail des épreuves. */
function renderBibPreparationOverview(array $tabEpreuves) {
function renderBibPreparationOverview(array $tabEpreuves, $strAnomBadges = '') {
$intRegistered = 0;
$intAssigned = 0;
@ -4827,9 +4830,11 @@ function renderBibPreparationOverview(array $tabEpreuves) {
}
$intPending = max(0, $intRegistered - $intAssigned);
$tabStats = [
$tabQuantityStats = [
['value' => count($tabEpreuves), 'key' => 'bib_v5_stat_races', 'tone' => ''],
['value' => $intRegistered, 'key' => 'bib_v5_stat_registered', 'tone' => ''],
];
$tabBibStats = [
['value' => $intAssigned, 'key' => 'bib_v5_stat_assigned', 'tone' => 'success'],
['value' => $intPending, 'key' => 'bib_v5_stat_pending', 'tone' => $intPending > 0 ? 'warning' : 'success'],
];
@ -4840,14 +4845,38 @@ function renderBibPreparationOverview(array $tabEpreuves) {
<div class="bib-workspace-panel-heading">
<p><?php fxBibTexteTrad('bib_v5_preparation_intro', 1); ?></p>
</div>
<dl class="bib-preparation-stats">
<?php foreach ($tabStats as $tabStat) { ?>
<div class="bib-preparation-stat<?php echo $tabStat['tone'] !== '' ? ' bib-preparation-stat--' . fxBibEsc($tabStat['tone']) : ''; ?>">
<dd data-bib-overview-stat="<?php echo fxBibEsc($tabStat['key']); ?>"><?php echo (int)$tabStat['value']; ?></dd>
<dt><?php fxBibTexteTrad($tabStat['key'], 1); ?></dt>
</div>
<?php } ?>
</dl>
<div class="bib-preparation-groups">
<section class="bib-preparation-group bib-preparation-group--quantities">
<h3><?php fxBibTexteTrad('bib_v5_group_quantities', 1); ?></h3>
<dl class="bib-preparation-stats">
<?php foreach ($tabQuantityStats as $tabStat) { ?>
<div class="bib-preparation-stat">
<dd data-bib-overview-stat="<?php echo fxBibEsc($tabStat['key']); ?>"><?php echo (int)$tabStat['value']; ?></dd>
<dt><?php fxBibTexteTrad($tabStat['key'], 1); ?></dt>
</div>
<?php } ?>
</dl>
<nav class="bib-tool-nav bib-tool-nav--group" aria-label="<?php echo fxBibEsc(fxBibTexte('bib_v5_group_quantities', 0)); ?>">
<?php echo renderBibToolNavBtn('qty_summary', 'bib_v4_qty_summary_title'); ?>
</nav>
</section>
<section class="bib-preparation-group bib-preparation-group--bibs">
<h3><?php fxBibTexteTrad('bib_v5_group_bibs', 1); ?></h3>
<dl class="bib-preparation-stats">
<?php foreach ($tabBibStats as $tabStat) { ?>
<div class="bib-preparation-stat<?php echo $tabStat['tone'] !== '' ? ' bib-preparation-stat--' . fxBibEsc($tabStat['tone']) : ''; ?>">
<dd data-bib-overview-stat="<?php echo fxBibEsc($tabStat['key']); ?>"><?php echo (int)$tabStat['value']; ?></dd>
<dt><?php fxBibTexteTrad($tabStat['key'], 1); ?></dt>
</div>
<?php } ?>
</dl>
<nav class="bib-tool-nav bib-tool-nav--group bib-tool-nav--group-bibs" aria-label="<?php echo fxBibEsc(fxBibTexte('bib_v5_group_bibs', 0)); ?>">
<?php echo renderBibToolNavBtn('anomalies', 'bib_v4_anomalies_title', $strAnomBadges); ?>
<?php echo renderBibToolNavBtn('dist_print', 'bib_v4_dist_print_title'); ?>
</nav>
</section>
</div>
</div>
<?php
return ob_get_clean();
@ -4945,19 +4974,13 @@ function renderBibToolNav($int_eve_id, $tabEpreuves, $strLangue = 'fr') {
<div class="bib-tool-hub">
<nav class="bib-workspace-nav" role="tablist" aria-label="<?php echo fxBibEsc($strNavLabel); ?>">
<?php echo renderBibWorkspaceTab('preparation', 'bib_v5_workspace_preparation', true); ?>
<?php echo renderBibWorkspaceTab('production', 'bib_v5_workspace_production'); ?>
<?php echo renderBibWorkspaceTab('operations', 'bib_v5_workspace_operations'); ?>
<?php echo renderBibWorkspaceTab('settings', 'bib_v5_workspace_settings'); ?>
<?php echo renderBibWorkspaceTab('production', 'bib_v5_workspace_production'); ?>
</nav>
<section class="bib-workspace-panel" data-bib-workspace-panel="preparation">
<?php echo renderBibPreparationOverview($tabEpreuves); ?>
<nav class="bib-tool-nav bib-tool-nav--preparation" aria-label="<?php echo fxBibEsc(fxBibTexte('bib_v5_workspace_preparation', 0)); ?>">
<?php echo renderBibToolNavBtn('qty_summary', 'bib_v4_qty_summary_title'); ?>
<?php if (fxBibGlobalBatchToolIsAvailable($int_eve_id, $tabEpreuves)) {
echo renderBibToolNavBtn('global_batch', 'bib_v4_global_batch_title');
} ?>
</nav>
<?php echo renderBibPreparationOverview($tabEpreuves, $strAnomBadges); ?>
</section>
<section class="bib-workspace-panel bib-ui-hidden" data-bib-workspace-panel="production">
@ -4966,11 +4989,12 @@ function renderBibToolNav($int_eve_id, $tabEpreuves, $strLangue = 'fr') {
<section class="bib-workspace-panel bib-ui-hidden" data-bib-workspace-panel="operations">
<div class="bib-workspace-panel-heading">
<p><?php fxBibTexteTrad('bib_v5_operations_intro', 1); ?></p>
<p><?php fxBibTexteTrad('bib_v5_modes_intro', 1); ?></p>
</div>
<nav class="bib-tool-nav bib-tool-nav--operations" aria-label="<?php echo fxBibEsc(fxBibTexte('bib_v5_workspace_operations', 0)); ?>">
<?php echo renderBibToolNavBtn('anomalies', 'bib_v4_anomalies_title', $strAnomBadges); ?>
<?php echo renderBibToolNavBtn('dist_print', 'bib_v4_dist_print_title'); ?>
<?php if (fxBibGlobalBatchToolIsAvailable($int_eve_id, $tabEpreuves)) {
echo renderBibToolNavBtn('global_batch', 'bib_v4_global_batch_title');
} ?>
</nav>
</section>
@ -5526,8 +5550,9 @@ function fxShowBibTool4($str_code, $int_eve_id, $strLangue){
$blnHasLockedRanges = fxBibEpreuveHasLockedRanges((int)$tabEpreuves[$i]['epr_id']);
$intSeqCount = fxBibCountSavedRanges($tabBibStats);
$intPending = (int)($infoBib['a_assigner'] ?? 0);
$tabQuantites = fxGetQuantites((int)$tabEpreuves[$i]['epr_id']);
$intPlacesAvailable = (int)($tabQuantites['qte_restante'] ?? 0);
$blnRaceExpanded = ($i === 1);
$blnRaceReady = ($intPending === 0 && $intSeqCount > 0);
?>
@ -5552,25 +5577,36 @@ function fxShowBibTool4($str_code, $int_eve_id, $strLangue){
<strong><?php echo fxBibEsc(fxBibEpreuveDisplayName($tabEpreuves[$i], $strLangue)); ?></strong>
<span><?php echo fxBibEsc(trim($tabEpreuves[$i]['epr_nom_' . $strLangue] ?? '')); ?></span>
</div>
<dl class="bib-race-summary__stats">
<div>
<dd><span class="bib-race-summary-assigned"><?php echo (int)($infoBib['avec_bib'] ?? 0); ?></span> / <span class="bib-race-summary-total"><?php echo (int)($infoBib['total'] ?? 0); ?></span></dd>
<dt><?php fxBibTexteTrad('bib_v5_stat_assigned', 1); ?></dt>
</div>
<div>
<dd class="bib-race-summary-ranges"><?php echo $intSeqCount; ?></dd>
<dt><?php fxBibTexteTrad('bib_v5_production_ranges', 1); ?></dt>
</div>
<div>
<dd class="bib-race-summary-pending"><?php echo $intPending; ?></dd>
<dt><?php fxBibTexteTrad('bib_v5_stat_pending', 1); ?></dt>
</div>
</dl>
<span class="bib-race-summary__status<?php echo $blnRaceReady ? ' is-ready' : ''; ?>"
data-label-ready="<?php echo fxBibEsc(fxBibTexte('bib_v5_race_ready', 0)); ?>"
data-label-incomplete="<?php echo fxBibEsc(fxBibTexte('bib_v5_race_incomplete', 0)); ?>">
<?php fxBibTexteTrad($blnRaceReady ? 'bib_v5_race_ready' : 'bib_v5_race_incomplete', 1); ?>
</span>
<section class="bib-race-summary__group bib-race-summary__group--quantities">
<h4><?php fxBibTexteTrad('bib_v5_group_quantities', 1); ?></h4>
<dl class="bib-race-summary__stats">
<div>
<dd class="bib-race-summary-total"><?php echo (int)($infoBib['total'] ?? 0); ?></dd>
<dt><?php fxBibTexteTrad('bib_v5_stat_registered', 1); ?></dt>
</div>
<div>
<dd class="bib-race-summary-available"><?php echo $intPlacesAvailable; ?></dd>
<dt><?php echo fxBibEsc(fxBibSiteOrBibTexte('promoteur_qte_epr_qte', 'bib_v4_summary_dispo')); ?></dt>
</div>
</dl>
</section>
<section class="bib-race-summary__group bib-race-summary__group--bibs">
<h4><?php fxBibTexteTrad('bib_v5_group_bibs', 1); ?></h4>
<dl class="bib-race-summary__stats">
<div>
<dd class="bib-race-summary-assigned"><?php echo (int)($infoBib['avec_bib'] ?? 0); ?></dd>
<dt><?php fxBibTexteTrad('bib_v5_stat_assigned', 1); ?></dt>
</div>
<div>
<dd class="bib-race-summary-ranges"><?php echo $intSeqCount; ?></dd>
<dt><?php fxBibTexteTrad('bib_v5_production_ranges', 1); ?></dt>
</div>
<div>
<dd class="bib-race-summary-pending"><?php echo $intPending; ?></dd>
<dt><?php fxBibTexteTrad('bib_v5_stat_pending', 1); ?></dt>
</div>
</dl>
</section>
<button type="button"
class="bib-race-toggle"
data-label-expand="<?php echo fxBibEsc(fxBibTexte('bib_v4_expand', 0)); ?>"

View File

@ -7,7 +7,7 @@
* Constantes *
*
**************/
define('_VERSION_CODE', '4.72.843');
define('_VERSION_CODE', '4.72.844');
define('_DATE_CODE', '2026-07-21');
//MSIN-4290
define('QR_SECRET_KEY', 'ms1_qr_2026_cle_secrete_longue_et_fixe');

View File

@ -11,6 +11,9 @@ WHERE info_prg = 'compte.php'
'bib_v5_workspace_operations',
'bib_v5_workspace_settings',
'bib_v5_preparation_intro',
'bib_v5_group_quantities',
'bib_v5_group_bibs',
'bib_v5_modes_intro',
'bib_v5_stat_races',
'bib_v5_stat_registered',
'bib_v5_stat_assigned',

View File

@ -42,6 +42,12 @@ FROM (
UNION ALL SELECT 'bib_v5_workspace_settings', 'en', 'Settings', 'Rules that apply to the entire event.'
UNION ALL SELECT 'bib_v5_preparation_intro', 'fr', 'Préparez les épreuves et attribuez les dossards aux inscriptions.', ''
UNION ALL SELECT 'bib_v5_preparation_intro', 'en', 'Prepare races and assign bibs to registrations.', ''
UNION ALL SELECT 'bib_v5_group_quantities', 'fr', 'Quantités', ''
UNION ALL SELECT 'bib_v5_group_quantities', 'en', 'Quantities', ''
UNION ALL SELECT 'bib_v5_group_bibs', 'fr', 'Dossards', ''
UNION ALL SELECT 'bib_v5_group_bibs', 'en', 'Bibs', ''
UNION ALL SELECT 'bib_v5_modes_intro', 'fr', 'Utilisez les modes dassignation qui traitent plusieurs épreuves ou des besoins particuliers.', ''
UNION ALL SELECT 'bib_v5_modes_intro', 'en', 'Use assignment modes that process multiple races or special requirements.', ''
UNION ALL SELECT 'bib_v5_stat_races', 'fr', 'Épreuves actives', ''
UNION ALL SELECT 'bib_v5_stat_races', 'en', 'Active races', ''
UNION ALL SELECT 'bib_v5_stat_registered', 'fr', 'Inscriptions', ''