Refactor ChronoTrack API push panel to enhance user experience with clearer status messages and improved layout. Update button actions and add collapsible details section for better visibility of synchronization results. This change aims to streamline participant data management and provide more intuitive feedback during the push process.
This commit is contained in:
@ -246,24 +246,42 @@ function fxChronotrackApiAdminRenderRaceMapping($intEveId, $arrConfig, $strLangu
|
||||
|
||||
function fxChronotrackApiAdminRenderPushPanel($intEveId, $blnClosed = false) {
|
||||
echo '<div class="card mb-4 border-primary" id="ct_api_push_card">';
|
||||
echo '<div class="card-header">Synchronisation manuelle (participants)</div>';
|
||||
echo '<div class="card-header">Synchronisation ChronoTrack</div>';
|
||||
echo '<div class="card-body">';
|
||||
if ($blnClosed) {
|
||||
echo '<div class="alert alert-warning py-2 small mb-2">Événement fermé — push manuel autorisé pour tests ou rattrapage.</div>';
|
||||
echo '<div class="alert alert-warning py-2 small mb-2">Événement fermé — envoi manuel encore possible.</div>';
|
||||
}
|
||||
echo '<p class="small text-muted mb-2">Push <strong>différentiel</strong> MS1 → ChronoTrack '
|
||||
. '(nouveaux / modifiés depuis le dernier push OK). External ID = <code>par_id_original</code>.</p>';
|
||||
echo '<div id="ct_api_push_summary" class="mb-2 text-muted small">Cliquez <strong>Actualiser</strong>.</div>';
|
||||
echo '<div id="ct_api_push_blocked_wrap" class="mb-2 d-none"></div>';
|
||||
echo '<div class="mb-2">';
|
||||
echo '<button type="button" class="btn btn-primary btn-sm" id="ct_api_btn_push" disabled>';
|
||||
echo '<i class="fa fa-cloud-upload" aria-hidden="true"></i> Pousser le différentiel</button> ';
|
||||
echo '<button type="button" class="btn btn-outline-secondary btn-sm" id="ct_api_btn_push_refresh">';
|
||||
|
||||
// Zone employé : statut clair + actions d’abord. MSIN-4328
|
||||
echo '<div id="ct_api_push_status" class="ct-api-push-status mb-3">';
|
||||
echo '<div class="text-muted small">Cliquez <strong>Actualiser</strong> pour vérifier s’il y a des changements à envoyer.</div>';
|
||||
echo '</div>';
|
||||
|
||||
echo '<div class="ct-api-push-actions mb-2">';
|
||||
echo '<button type="button" class="btn btn-outline-secondary" id="ct_api_btn_push_refresh">';
|
||||
echo '<i class="fa fa-refresh" aria-hidden="true"></i> Actualiser</button> ';
|
||||
echo '<button type="button" class="btn btn-primary btn-lg" id="ct_api_btn_push" disabled>';
|
||||
echo '<i class="fa fa-cloud-upload" aria-hidden="true"></i> Envoyer vers ChronoTrack</button>';
|
||||
echo '</div>';
|
||||
echo '<p class="small text-muted mb-2">La sync automatique arrivera bientôt — pour l’instant, un clic suffit quand il y a du nouveau.</p>';
|
||||
echo '<div id="ct_api_push_result" class="small mb-3"></div>';
|
||||
|
||||
// Détails / debug : sous les boutons, repliés par défaut
|
||||
echo '<div class="card border-light mb-0" id="ct_api_push_details_card">';
|
||||
echo '<div class="card-header py-2 bg-white">';
|
||||
echo '<a class="d-block text-muted small collapsed" data-toggle="collapse" href="#ct_api_push_details_collapse" '
|
||||
. 'role="button" aria-expanded="false">';
|
||||
echo 'Détails & exclus <span class="text-muted">(compteurs, liste à corriger)</span>';
|
||||
echo '</a></div>';
|
||||
echo '<div class="collapse" id="ct_api_push_details_collapse"><div class="card-body py-2">';
|
||||
echo '<div id="ct_api_push_summary" class="mb-2 text-muted small"></div>';
|
||||
echo '<div id="ct_api_push_blocked_wrap" class="mb-2 d-none"></div>';
|
||||
echo '<button type="button" class="btn btn-outline-info btn-sm" id="ct_api_btn_ct_count">';
|
||||
echo '<i class="fa fa-calculator" aria-hidden="true"></i> Nb ChronoTrack Live</button>';
|
||||
echo '</div>';
|
||||
echo '<div id="ct_api_push_result" class="small mt-2"></div>';
|
||||
echo '<p class="small text-muted mt-2 mb-0">Info technique : external ID = <code>par_id_original</code>. '
|
||||
. 'Le comptage Live sert aussi à lier les entry_id pour le bouton fiche.</p>';
|
||||
echo '</div></div></div>';
|
||||
|
||||
echo '</div></div>';
|
||||
}
|
||||
|
||||
@ -309,6 +327,32 @@ function fxChronotrackApiAdminRenderPageScript($intEveId, $arrConfig, $blnClosed
|
||||
#ct_api_push_summary .ct-api-dash-table td.num { text-align: right; font-variant-numeric: tabular-nums; font-weight: 600; }
|
||||
#ct_api_push_summary .ct-api-dash-push { font-size: 0.85rem; margin-bottom: 0; }
|
||||
#ct_api_config_collapse .card { box-shadow: none; }
|
||||
.ct-api-push-status {
|
||||
padding: 12px 14px;
|
||||
border-radius: 8px;
|
||||
background: #f8f9fa;
|
||||
border: 1px solid #e9ecef;
|
||||
}
|
||||
.ct-api-push-status--ok {
|
||||
background: #e8f7ee;
|
||||
border-color: #b7e4c7;
|
||||
}
|
||||
.ct-api-push-status--todo {
|
||||
background: #fff8e6;
|
||||
border-color: #ffe1a6;
|
||||
}
|
||||
.ct-api-push-status__title {
|
||||
font-size: 1.15rem;
|
||||
font-weight: 700;
|
||||
margin: 0 0 4px;
|
||||
line-height: 1.3;
|
||||
}
|
||||
.ct-api-push-status__hint {
|
||||
margin: 0;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
.ct-api-push-actions .btn-lg { font-size: 1.05rem; padding: 0.55rem 1.1rem; }
|
||||
#ct_api_push_details_card .card-header a { text-decoration: none; }
|
||||
</style>
|
||||
<?php fxChronotrackApiAdminRenderLoaderAssets($vDomaine); ?>
|
||||
<script>
|
||||
@ -800,13 +844,20 @@ function fxChronotrackApiAdminRenderPageScript($intEveId, $arrConfig, $blnClosed
|
||||
|
||||
function renderPushPreview(res) {
|
||||
var $sum = $('#ct_api_push_summary');
|
||||
var $status = $('#ct_api_push_status');
|
||||
var $btn = $('#ct_api_btn_push');
|
||||
objPushPreview = res;
|
||||
if (!$sum.length) {
|
||||
if (!$sum.length && !$status.length) {
|
||||
return;
|
||||
}
|
||||
if (!res || res.state !== 'ok') {
|
||||
$sum.html('<div class="text-danger">' + escHtml((res && res.message) ? res.message : 'Erreur') + '</div>');
|
||||
if ($status.length) {
|
||||
$status.removeClass('ct-api-push-status--ok ct-api-push-status--todo')
|
||||
.html('<div class="text-danger">' + escHtml((res && res.message) ? res.message : 'Erreur') + '</div>');
|
||||
}
|
||||
if ($sum.length) {
|
||||
$sum.html('');
|
||||
}
|
||||
$('#ct_api_push_blocked_wrap').addClass('d-none').empty();
|
||||
$btn.prop('disabled', true);
|
||||
return;
|
||||
@ -821,6 +872,34 @@ function fxChronotrackApiAdminRenderPageScript($intEveId, $arrConfig, $blnClosed
|
||||
var blnFirst = !!res.is_first_push;
|
||||
var strLastPush = res.last_push_at || null;
|
||||
|
||||
// Bannière employé (ludique / claire)
|
||||
if ($status.length) {
|
||||
$status.removeClass('ct-api-push-status--ok ct-api-push-status--todo');
|
||||
if (intPending > 0) {
|
||||
$status.addClass('ct-api-push-status--todo');
|
||||
var strTodoTitle = blnFirst
|
||||
? (intPending + ' à envoyer (premier envoi)')
|
||||
: (intPending + ' changement' + (intPending > 1 ? 's' : '') + ' à envoyer');
|
||||
$status.html(
|
||||
'<p class="ct-api-push-status__title">' + escHtml(strTodoTitle) + '</p>'
|
||||
+ '<p class="ct-api-push-status__hint mb-0">Cliquez <strong>Envoyer vers ChronoTrack</strong> — seuls les nouveaux / modifiés partent.</p>'
|
||||
);
|
||||
} else {
|
||||
$status.addClass('ct-api-push-status--ok');
|
||||
var strOk = 'Tout est à jour';
|
||||
if (strLastPush) {
|
||||
strOk += ' <span class="text-muted font-weight-normal" style="font-size:0.85rem;">· dernier envoi '
|
||||
+ escHtml(strLastPush) + '</span>';
|
||||
}
|
||||
$status.html(
|
||||
'<p class="ct-api-push-status__title text-success">' + strOk + '</p>'
|
||||
+ '<p class="ct-api-push-status__hint mb-0 text-muted">'
|
||||
+ intEligible + ' éligibles · rien à envoyer pour le moment.</p>'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Détails (sous les boutons, zone repliable)
|
||||
var html = '<table class="table table-sm table-bordered ct-api-dash-table mb-1">';
|
||||
html += '<thead><tr><th>MS1</th><th class="text-right">Total</th><th class="text-right">Éligibles</th>';
|
||||
html += '<th class="text-right">Exclus</th><th class="text-right">Différentiel</th></tr></thead><tbody>';
|
||||
@ -836,30 +915,21 @@ function fxChronotrackApiAdminRenderPageScript($intEveId, $arrConfig, $blnClosed
|
||||
+ intCtLiveCount + '</strong> inscription(s) '
|
||||
+ '<button type="button" class="btn btn-link btn-sm p-0 align-baseline" id="ct_api_btn_ct_count_inline">recompter</button></p>';
|
||||
} else {
|
||||
html += '<p class="ct-api-dash-push mb-1 text-muted">ChronoTrack Live : total non chargé '
|
||||
+ '(bouton <em>Nb ChronoTrack Live</em> — optionnel).</p>';
|
||||
}
|
||||
|
||||
if (intPending > 0) {
|
||||
html += '<p class="ct-api-dash-push mb-1"><strong>À pousser :</strong> '
|
||||
+ intPending + (blnFirst ? ' (premier envoi / baseline)' : ' modifié(s) depuis le dernier push')
|
||||
+ '</p>';
|
||||
} else {
|
||||
html += '<p class="ct-api-dash-push mb-1 text-success"><strong>À jour</strong> — rien à repousser';
|
||||
if (strLastPush) {
|
||||
html += ' <span class="text-muted">(dernier push ' + escHtml(strLastPush) + ')</span>';
|
||||
}
|
||||
html += '</p>';
|
||||
html += '<p class="ct-api-dash-push mb-1 text-muted">ChronoTrack Live : total non chargé (bouton ci-dessous).</p>';
|
||||
}
|
||||
|
||||
$sum.html(html);
|
||||
renderBlockedPanel(res);
|
||||
$btn.prop('disabled', intPending <= 0);
|
||||
// Ouvre les détails seulement s’il y a des exclus à corriger
|
||||
if (intBlocked > 0) {
|
||||
$('#ct_api_push_details_collapse').collapse('show');
|
||||
}
|
||||
}
|
||||
|
||||
function renderPushResult(res, strTitle) {
|
||||
var $res = $('#ct_api_push_result');
|
||||
var strHeading = strTitle || 'Résultat du push';
|
||||
var strHeading = strTitle || 'Résultat';
|
||||
var strClass = 'text-danger';
|
||||
if (res && res.state === 'warning') {
|
||||
strClass = 'text-warning';
|
||||
@ -881,7 +951,8 @@ function fxChronotrackApiAdminRenderPageScript($intEveId, $arrConfig, $blnClosed
|
||||
|
||||
function loadPushPreview(blnForce) {
|
||||
var $sum = $('#ct_api_push_summary');
|
||||
if (!$sum.length) {
|
||||
var $status = $('#ct_api_push_status');
|
||||
if (!$sum.length && !$status.length) {
|
||||
return;
|
||||
}
|
||||
if (xhrPushPreview && xhrPushPreview.readyState !== 4) {
|
||||
@ -890,7 +961,10 @@ function fxChronotrackApiAdminRenderPageScript($intEveId, $arrConfig, $blnClosed
|
||||
}
|
||||
xhrPushPreview.abort();
|
||||
}
|
||||
$sum.html(waitHtml('Lecture MS1 (éligibles / différentiel)…'));
|
||||
if ($status.length) {
|
||||
$status.removeClass('ct-api-push-status--ok ct-api-push-status--todo')
|
||||
.html(waitHtml('Vérification des changements…'));
|
||||
}
|
||||
xhrPushPreview = $.ajax({
|
||||
url: strAjaxUrl,
|
||||
type: 'POST',
|
||||
@ -910,7 +984,10 @@ function fxChronotrackApiAdminRenderPageScript($intEveId, $arrConfig, $blnClosed
|
||||
var strMsg = (strStatus === 'timeout')
|
||||
? 'Délai dépassé — réessayez Actualiser.'
|
||||
: 'Erreur réseau (preview).';
|
||||
$sum.html('<div class="text-danger">' + escHtml(strMsg) + '</div>');
|
||||
if ($status.length) {
|
||||
$status.removeClass('ct-api-push-status--ok ct-api-push-status--todo')
|
||||
.html('<div class="text-danger">' + escHtml(strMsg) + '</div>');
|
||||
}
|
||||
}).always(function () {
|
||||
xhrPushPreview = null;
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user