/**
* MSIN-4435 / MSIN-4440 — Bib assignments v4 (#module-bib)
* Chargé uniquement sur inc_tableau_gestion_epreuves.
*/
(function () {
'use strict';
const moduleBib = document.getElementById('module-bib');
if (moduleBib) {
function bibAjaxLangSuffix() {
var lang = moduleBib.dataset.lang || 'fr';
return '&lang=' + encodeURIComponent(lang)
+ '&csrf_token=' + encodeURIComponent(bibCsrfToken());
}
function bibJs(attr) {
return moduleBib.dataset[attr] || '';
}
function bibJsConfirm(attr) {
return bibJs(attr).replace(/\\n/g, '\n');
}
function bibJsFmt(attr) {
var tpl = bibJs(attr);
var args = Array.prototype.slice.call(arguments, 1);
var i = 0;
return tpl.replace(/%d/g, function () {
return String(args[i++] ?? 0);
});
}
var bibLoaderDepth = 0;
function bibLoaderShow() {
if (!window.Ms1Loader) {
return;
}
bibLoaderDepth++;
if (bibLoaderDepth === 1) {
var msg = bibJs('jsLoaderWait');
Ms1Loader.show(msg || undefined);
}
}
function bibLoaderHide() {
if (!window.Ms1Loader) {
return;
}
bibLoaderDepth = Math.max(0, bibLoaderDepth - 1);
if (bibLoaderDepth === 0) {
Ms1Loader.hide();
}
}
/** fetch ajax_bib_range.php — loader plein ecran par defaut (compteur si appels imbriques). */
function bibFetch(url, options, settings) {
settings = settings || {};
var useLoader = settings.loader !== false;
if (useLoader) {
bibLoaderShow();
}
return fetch(url, options).finally(function () {
if (useLoader) {
bibLoaderHide();
}
});
}
var BIB_BATCH_CHUNK_SIZE = 50;
function bibBatchProgressShow(processed, total) {
var intTotal = total > 0 ? total : 1;
var msg = bibJsFmt('jsBatchProgress', processed, intTotal);
if (window.Ms1Loader && Ms1Loader.showProgress) {
Ms1Loader.showProgress(processed, intTotal, msg);
} else {
bibLoaderShow();
}
}
function bibBatchProgressHide() {
if (window.Ms1Loader && Ms1Loader.hide) {
Ms1Loader.hide();
} else {
bibLoaderHide();
}
}
/** MSIN-4436 — Force la fermeture du loader (batch global : évite overlay bloqué). */
function bibBatchProgressForceHide() {
bibLoaderDepth = 0;
bibBatchProgressHide();
}
function bibAfterBatchGoSuccess(row, data, isResetMode, options) {
options = options || {};
let existing = document.querySelector('.epr-row-view');
if (existing) {
existing.remove();
}
if (data.html) {
row.insertAdjacentHTML('afterend', data.html);
}
bibAfterBatchGoRefreshOnly(row, isResetMode, options);
}
function bibAfterBatchGoRefreshOnly(row, isResetMode, options) {
options = options || {};
if (!row) {
return Promise.resolve();
}
if (isResetMode) {
row.classList.remove('reset-mode');
row.dataset.mode = '';
let btnReset = row.querySelector('.btn-reset');
if (btnReset) {
btnReset.textContent = row.dataset.resetLabel || btnReset.textContent;
}
}
row.classList.remove('batch-mode');
let container = row.querySelector('.bib-container');
if (container) {
container.classList.remove('batch-mode');
}
let btnBatch = row.querySelector('.btn-assign-batch');
if (btnBatch) {
btnBatch.textContent = row.dataset.batchLabel || btnBatch.textContent;
}
row.querySelectorAll('.bib-start, .bib-qty, .bib-end').forEach(input => {
input.removeAttribute('readonly');
});
row.querySelectorAll('.batch-select-range').forEach(cb => {
cb.checked = false;
cb.disabled = false;
});
syncBibUiState(row);
var useLoader = options.loader !== false;
var skipAnomalies = options.skipAnomalies === true;
var refreshLite = options.refreshLite === true || isResetMode === true;
return bibFetch('/ajax_bib_range.php', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body:
'action=refresh_ranges'
+ '&epr_id=' + encodeURIComponent(row.dataset.eprId)
+ '&mode=assign'
+ (refreshLite ? '&lite=1' : '')
+ bibAjaxLangSuffix()
}, { loader: useLoader })
.then(function (res) {
if (!res.ok) {
throw new Error(bibJs('jsErrGeneric'));
}
return res.json();
})
.then(function (refresh) {
if (!refresh.success) {
return;
}
let containerRef = setBibContainerFromAjax(row, refresh, { skipAnomalies: skipAnomalies });
if (!containerRef) {
return;
}
return bibFetch('/ajax_bib_range.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body:
'action=batch_analysis'
+ '&epr_id=' + encodeURIComponent(row.dataset.eprId)
+ bibAjaxLangSuffix()
}, { loader: false })
.then(function (res) { return res.json(); })
.then(function (stats) {
if (!stats.success) {
return;
}
bibSyncEprBibStats(row, stats.info);
syncBibUiState(row);
});
});
}
function bibGetRowSortKeys(row) {
if (!row) {
return { sort1: '', sort2: '' };
}
// MSIN-4456 — Lire explicitement primaire vs secondaire (évite toute ambiguïté de sélecteur).
var wrap1 = row.querySelector('.epr-batch-order-wrap:not(.epr-batch-order-wrap--secondary)');
var wrap2 = row.querySelector('.epr-batch-order-wrap--secondary');
var s1 = (wrap1 && wrap1.querySelector('select.batch-order'))
|| row.querySelector('select.batch-order');
var s2 = (wrap2 && wrap2.querySelector('select.batch-order-2'))
|| row.querySelector('select.batch-order-2');
return {
sort1: s1 ? String(s1.value || '').trim() : '',
sort2: s2 ? String(s2.value || '').trim() : ''
};
}
function bibGetGlobalBatchSortKeys(panel) {
if (!panel) {
return { sort1: '', sort2: '' };
}
var s1 = panel.querySelector('.bib-global-batch-order')
|| panel.querySelector('.bib-global-gen-batch-order')
|| panel.querySelector('.bib-global-free-batch-order');
var s2 = panel.querySelector('.bib-global-batch-order-2')
|| panel.querySelector('.bib-global-gen-batch-order-2')
|| panel.querySelector('.bib-global-free-batch-order-2');
return {
sort1: s1 ? s1.value : '',
sort2: s2 ? s2.value : ''
};
}
function bibAppendBatchSortParams(body, sortKeys) {
sortKeys = sortKeys || {};
return body
+ '&sort_1=' + encodeURIComponent(sortKeys.sort1 || '')
+ '&sort_2=' + encodeURIComponent(sortKeys.sort2 || '');
}
function bibFetchBatchApplyChunk(row, selected, sortKeys, opts) {
opts = opts || {};
sortKeys = sortKeys || bibGetRowSortKeys(row);
var body =
'action=batch_apply_chunk'
+ '&epr_id=' + encodeURIComponent(row.dataset.eprId)
+ '&ranges=' + encodeURIComponent(JSON.stringify(selected))
+ bibAppendBatchSortParams('', sortKeys)
+ '&chunk_size=' + BIB_BATCH_CHUNK_SIZE
+ '&total_initial=' + (opts.totalInitial || 0)
+ '&batch_reset=' + (opts.batchReset ? 1 : 0)
+ bibAjaxLangSuffix();
return fetch('/ajax_bib_range.php', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: body
})
.then(function (res) {
if (!res.ok) {
throw new Error(bibJs('jsErrGeneric'));
}
return res.json();
})
.catch(function (err) {
if (err && err.message) {
throw err;
}
throw new Error(bibJs('jsErrGeneric'));
});
}
function bibRunBatchApplyChunks(row, selected, sortKeys, options) {
options = options || {};
var showResult = options.showResult !== false;
var manageLoader = options.manageLoader !== false;
var deferUiRefresh = options.deferUiRefresh === true;
var onProgress = options.onProgress;
var totalInitial = options.totalInitial > 0
? options.totalInitial
: bibRowPendingBibs(row);
var batchReset = true;
var chunkGuard = 0;
var maxChunks = Math.max(50, Math.ceil((totalInitial || 1) / BIB_BATCH_CHUNK_SIZE) + 5);
if (manageLoader) {
bibBatchProgressShow(0, totalInitial > 0 ? totalInitial : 1);
}
function runChunk() {
chunkGuard++;
if (chunkGuard > maxChunks) {
return Promise.reject(new Error(bibJs('jsErrGeneric')));
}
return bibFetchBatchApplyChunk(row, selected, sortKeys, {
batchReset: batchReset,
totalInitial: totalInitial
}).then(function (data) {
if (!data || !data.success) {
throw new Error((data && data.message) || bibJs('jsErrGeneric'));
}
if (data.total_initial) {
totalInitial = data.total_initial;
}
batchReset = false;
var processed = data.processed || 0;
if (onProgress) {
onProgress(processed, totalInitial);
} else if (manageLoader) {
bibBatchProgressShow(processed, totalInitial);
}
if (data.complete) {
if (showResult) {
bibAfterBatchGoSuccess(row, data, false);
} else if (!deferUiRefresh) {
bibAfterBatchGoRefreshOnly(row, false, { loader: false, skipAnomalies: true });
}
return data;
}
return runChunk();
});
}
return runChunk()
.catch(function (err) {
if (manageLoader) {
alert(err.message || bibJs('jsErrGeneric'));
}
throw err;
})
.finally(function () {
if (manageLoader) {
bibBatchProgressHide();
}
});
}
// MSIN-4436 — Batch global (épreuves solo), chargement différé à l'ouverture.
function bibGetGlobalBatchPanel() {
return document.getElementById('bib-global-batch');
}
/** Corps du panneau (dans #bib-tool-detail-body une fois l'outil ouvert). */
function bibGetGlobalBatchBody() {
var detailBody = document.getElementById('bib-tool-detail-body');
if (detailBody) {
var inDetail = detailBody.querySelector('.bib-global-batch__body');
if (inDetail) {
return inDetail;
}
}
var panel = bibGetGlobalBatchPanel();
return panel ? panel.querySelector('.bib-global-batch__body') : null;
}
function bibGetGlobalBatchExistingSection() {
var body = bibGetGlobalBatchBody();
return body ? body.querySelector('.bib-global-batch--existing') : null;
}
function bibGetGlobalBatchGeneratedSection() {
var body = bibGetGlobalBatchBody();
return body ? body.querySelector('.bib-global-batch--generated') : null;
}
function bibGetGlobalBatchFreeSection() {
var body = bibGetGlobalBatchBody();
return body ? body.querySelector('.bib-global-batch--free') : null;
}
function bibInvalidateGlobalBatchPanel() {
var mount = document.getElementById('bib-global-batch-mount');
var panel = bibGetGlobalBatchPanel();
if (panel) {
panel.removeAttribute('data-global-batch-loaded');
panel.setAttribute('data-global-batch-deferred', '1');
}
if (mount && panel) {
mount.innerHTML = ''
+ '
';
}
}
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();
});
}
function bibInsertGlobalSimView(html) {
bibRemoveGlobalSimViews();
var detailBody = document.getElementById('bib-tool-detail-body');
var anchor = bibGetGlobalBatchBody() || bibGetGlobalBatchPanel();
if (detailBody) {
detailBody.insertAdjacentHTML('beforeend', html);
return;
}
if (anchor) {
anchor.insertAdjacentHTML('afterend', html);
}
}
// MSIN-4440 — Grille outils : un panneau de détail, contenu déplacé depuis #bib-tool-store.
var bibActiveTool = null;
// MSIN-4467 — Espace principal : préparation, production, opérations ou réglages.
var bibActiveWorkspace = 'preparation';
var bibToolContentSlots = {};
function bibSetWorkspace(workspaceId, options) {
options = options || {};
if (!workspaceId) {
return;
}
var panel = moduleBib.querySelector('[data-bib-workspace-panel="' + workspaceId + '"]');
if (!panel) {
return;
}
if (options.keepTool !== true) {
bibCloseTool();
}
bibActiveWorkspace = workspaceId;
moduleBib.querySelectorAll('.bib-workspace-tab').forEach(function (tab) {
var active = tab.getAttribute('data-bib-workspace') === workspaceId;
tab.classList.toggle('is-active', active);
tab.setAttribute('aria-selected', active ? 'true' : 'false');
});
moduleBib.querySelectorAll('[data-bib-workspace-panel]').forEach(function (workspacePanel) {
workspacePanel.classList.toggle(
'bib-ui-hidden',
workspacePanel.getAttribute('data-bib-workspace-panel') !== workspaceId
);
});
var races = document.getElementById('bib-preparation-races');
if (races) {
races.classList.toggle('bib-ui-hidden', workspaceId !== 'preparation');
}
}
function bibWorkspaceForTool(toolId) {
if (toolId === 'event_config') {
return 'settings';
}
if (toolId === 'global_batch' || toolId === 'dist_print') {
return 'operations';
}
return 'preparation';
}
function bibGetToolPanel(toolId) {
return document.querySelector('#bib-tool-store [data-bib-tool="' + toolId + '"]');
}
function bibGetToolContentNode(panel, toolId) {
if (!panel) {
return null;
}
if (toolId === 'global_batch') {
return panel.querySelector('.bib-global-batch__body');
}
return panel.querySelector('.epr-content');
}
function bibInvalidateToolSlot(toolId) {
if (bibToolContentSlots[toolId]) {
delete bibToolContentSlots[toolId];
}
}
function bibRestoreToolContent(toolId) {
var slot = bibToolContentSlots[toolId];
if (!slot || !slot.content || !slot.placeholder || !slot.placeholder.parentNode) {
return;
}
slot.placeholder.parentNode.insertBefore(slot.content, slot.placeholder.nextSibling);
if (toolId === 'global_batch') {
slot.content.classList.add('bib-ui-hidden');
}
}
function bibMountToolContent(toolId) {
var panel = bibGetToolPanel(toolId);
var detailBody = document.getElementById('bib-tool-detail-body');
var content = bibGetToolContentNode(panel, toolId);
if (!panel || !detailBody || !content) {
return false;
}
if (!bibToolContentSlots[toolId]) {
var placeholder = document.createComment('bib-tool-slot-' + toolId);
content.parentNode.insertBefore(placeholder, content);
bibToolContentSlots[toolId] = {
content: content,
placeholder: placeholder,
panel: panel
};
}
detailBody.appendChild(content);
if (toolId === 'global_batch') {
content.classList.remove('bib-ui-hidden');
}
return true;
}
function bibSetActiveToolButton(toolId) {
moduleBib.querySelectorAll('.bib-tool-btn').forEach(function (btn) {
var active = !!toolId && btn.getAttribute('data-bib-tool') === toolId;
btn.classList.toggle('is-active', active);
btn.setAttribute('aria-expanded', active ? 'true' : 'false');
});
}
function bibSetToolDetailTitle(toolId) {
var titleEl = document.getElementById('bib-tool-detail-title');
if (!titleEl) {
return;
}
if (!toolId) {
titleEl.textContent = '';
return;
}
var btn = moduleBib.querySelector('.bib-tool-btn[data-bib-tool="' + toolId + '"]');
titleEl.textContent = btn
? (btn.getAttribute('data-bib-tool-label') || '')
: '';
}
function bibCloseTool() {
if (!bibActiveTool) {
return;
}
bibRestoreToolContent(bibActiveTool);
bibInvalidateToolSlot(bibActiveTool);
bibActiveTool = null;
bibSetActiveToolButton(null);
bibSetToolDetailTitle(null);
bibRemoveGlobalSimViews();
var detail = document.getElementById('bib-tool-detail');
var detailBody = document.getElementById('bib-tool-detail-body');
if (detailBody) {
detailBody.innerHTML = '';
}
if (detail) {
detail.classList.add('bib-ui-hidden');
}
}
function bibSyncToolNavBadges(toolId) {
var panel = bibGetToolPanel(toolId);
var btn = moduleBib.querySelector('.bib-tool-btn[data-bib-tool="' + toolId + '"]');
if (!panel || !btn) {
return;
}
var dest = btn.querySelector('.bib-tool-btn__badges');
if (!dest) {
return;
}
if (toolId === 'event_config') {
var srcNote = panel.querySelector('[data-bib-inter-epr-note]');
var destNote = dest.querySelector('[data-bib-inter-epr-note]');
if (srcNote && destNote) {
destNote.className = srcNote.className;
}
return;
}
if (toolId === 'qty_summary') {
dest.innerHTML = '';
return;
}
if (toolId === 'anomalies') {
var anomCount = panel.querySelector('.bib-anomalies-count');
var destBadge = dest.querySelector('[data-bib-anomalies-nav-badge]');
var strTodoFmt = bibJs('jsAnomaliesNavTodoFmt') || 'Élément à valider : %d';
var intCount = 0;
var blnPending = true;
if (anomCount) {
blnPending = anomCount.getAttribute('aria-busy') === 'true';
if (!blnPending) {
intCount = parseInt(String(anomCount.textContent || '').trim(), 10);
if (isNaN(intCount)) {
intCount = 0;
}
}
}
function bibAnomaliesNavBadgeLabel(count) {
return strTodoFmt.replace(/%d/g, String(count));
}
if (!destBadge) {
dest.innerHTML = '';
if (!blnPending && intCount > 0) {
var strLabel = bibAnomaliesNavBadgeLabel(intCount);
dest.innerHTML = '';
}
return;
}
if (blnPending || intCount <= 0) {
destBadge.classList.add('bib-ui-hidden');
destBadge.setAttribute('aria-hidden', 'true');
destBadge.textContent = '';
destBadge.removeAttribute('data-bib-anomalies-nav-count');
} else {
var strBadgeLabel = bibAnomaliesNavBadgeLabel(intCount);
destBadge.classList.remove('bib-ui-hidden');
destBadge.removeAttribute('aria-hidden');
destBadge.textContent = strBadgeLabel;
destBadge.setAttribute('title', strBadgeLabel);
destBadge.setAttribute('data-bib-anomalies-nav-count', String(intCount));
}
}
}
function bibSyncAllToolNavBadges() {
bibSyncToolNavBadges('event_config');
bibSyncToolNavBadges('anomalies');
}
function bibEnsureToolLoaded(toolId) {
if (toolId === 'qty_summary') {
var qtyPanel = bibGetToolPanel('qty_summary');
if (qtyPanel && qtyPanel.getAttribute('data-bib-qty-summary-deferred') === '1') {
return refreshBibQtySummaryPanel();
}
}
if (toolId === 'dist_print') {
var printPanel = bibGetToolPanel('dist_print');
if (printPanel && printPanel.getAttribute('data-bib-dist-print-deferred') === '1') {
return refreshBibDistPrintPanel();
}
}
if (toolId === 'global_batch') {
var batchPanel = bibGetToolPanel('global_batch');
if (batchPanel && batchPanel.getAttribute('data-global-batch-deferred') === '1') {
return bibEnsureGlobalBatchPanelLoaded();
}
}
return Promise.resolve();
}
function bibOpenTool(toolId) {
if (!toolId) {
return Promise.resolve();
}
var workspaceId = bibWorkspaceForTool(toolId);
if (bibActiveWorkspace !== workspaceId) {
bibSetWorkspace(workspaceId, { keepTool: true });
}
if (bibActiveTool === toolId) {
bibCloseTool();
return Promise.resolve();
}
var prevTool = bibActiveTool;
if (prevTool) {
bibRestoreToolContent(prevTool);
bibInvalidateToolSlot(prevTool);
}
bibRemoveGlobalSimViews();
return bibEnsureToolLoaded(toolId).then(function () {
var panel = bibGetToolPanel(toolId);
if (!panel || !bibMountToolContent(toolId)) {
return;
}
bibActiveTool = toolId;
bibSetActiveToolButton(toolId);
bibSetToolDetailTitle(toolId);
var detail = document.getElementById('bib-tool-detail');
if (detail) {
detail.classList.remove('bib-ui-hidden');
detail.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
}
if (toolId === 'global_batch') {
/* Sections repliées à l'arrivée — analyse au déploiement d'une section. */
}
bibSyncToolNavBadges(toolId);
initModuleBibTippy(document.getElementById('bib-tool-detail'));
});
}
function bibRemountActiveToolAfterRefresh(toolId) {
if (bibActiveTool !== toolId) {
return;
}
bibInvalidateToolSlot(toolId);
bibMountToolContent(toolId);
initModuleBibTippy(document.getElementById('bib-tool-detail'));
if (toolId === 'global_batch') {
/* Sections repliées à l'arrivée — analyse au déploiement d'une section. */
}
}
var bibGlobalBatchLoadPromise = null;
function bibEnsureGlobalBatchPanelLoaded() {
var mount = document.getElementById('bib-global-batch-mount');
var panel = bibGetGlobalBatchPanel();
if (!mount || !panel) {
return Promise.resolve(null);
}
if (panel.getAttribute('data-global-batch-loaded') === '1') {
return Promise.resolve(panel);
}
if (bibGlobalBatchLoadPromise) {
return bibGlobalBatchLoadPromise;
}
bibGlobalBatchLoadPromise = bibFetch('/ajax_bib_range.php', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body:
'action=global_batch_panel'
+ '&eve_id=' + encodeURIComponent(moduleBib.dataset.eveId || '')
+ bibAjaxLangSuffix()
})
.then(function (res) { return res.json(); })
.then(function (data) {
if (!data.success || !data.html) {
throw new Error(data.message || bibJs('jsErrGeneric'));
}
mount.innerHTML = data.html;
panel = bibGetGlobalBatchPanel();
if (panel) {
panel.setAttribute('data-global-batch-loaded', '1');
panel.removeAttribute('data-global-batch-deferred');
}
initModuleBibTippy(mount);
bibRemountActiveToolAfterRefresh('global_batch');
var freeSection = bibGetGlobalBatchFreeSection();
if (freeSection) {
bibBindGlobalFreeRange(freeSection);
}
return panel;
})
.finally(function () {
bibGlobalBatchLoadPromise = null;
});
return bibGlobalBatchLoadPromise;
}
function bibGlobalBatchSetToggleState(toggle, isOpen) {
if (!toggle) {
return;
}
toggle.setAttribute('aria-expanded', isOpen ? 'true' : 'false');
var label = isOpen
? (toggle.getAttribute('data-label-close') || '')
: (toggle.getAttribute('data-label-open') || '');
if (label) {
toggle.textContent = label;
}
}
function bibGlobalBatchOpenPanel(panel) {
if (!panel) {
return;
}
var body = panel.querySelector('.bib-global-batch__body');
var toggle = panel.querySelector('.bib-global-batch-toggle');
if (body) {
body.classList.remove('bib-ui-hidden');
}
bibGlobalBatchSetToggleState(toggle, true);
}
function bibSetGlobalBatchInfo(infoEl, text, state) {
if (!infoEl) {
return;
}
infoEl.textContent = text || '';
infoEl.classList.remove('text-muted', 'text-danger', 'text-warning', 'text-success');
if (state === 'error') {
infoEl.classList.add('text-danger');
} else if (state === 'warning') {
infoEl.classList.add('text-warning');
} else if (state === 'ok') {
infoEl.classList.add('text-success');
} else {
infoEl.classList.add('text-muted');
}
}
function bibCollectGlobalBatchPlans() {
var section = bibGetGlobalBatchExistingSection();
if (!section) {
return [];
}
var plans = [];
section.querySelectorAll('.bib-global-epr').forEach(function (eprBlock) {
var eprCb = eprBlock.querySelector('.bib-global-epr-select');
if (!eprCb || !eprCb.checked) {
return;
}
var eprId = parseInt(eprCb.dataset.eprId || eprBlock.dataset.eprId || '0', 10);
if (!eprId) {
return;
}
var ranges = [];
eprBlock.querySelectorAll('.bib-global-range-select:checked').forEach(function (rangeCb) {
ranges.push(rangeCb.dataset.rangeId);
});
if (ranges.length > 0) {
plans.push({ epr_id: eprId, ranges: ranges });
}
});
return plans;
}
function updateGlobalBatchAnalysis() {
var section = bibGetGlobalBatchExistingSection();
if (!section || !section.querySelector('.bib-global-epr-select')) {
return Promise.resolve();
}
var plans = bibCollectGlobalBatchPlans();
var infoEl = section.querySelector('.bib-global-batch__info');
var sortKeys = bibGetGlobalBatchSortKeys(section);
if (!infoEl) {
return Promise.resolve();
}
if (plans.length === 0) {
bibSetGlobalBatchInfo(
infoEl,
bibJs('jsGlobalNoEpr') || bibJs('jsBatchNone'),
'error'
);
return Promise.resolve(null);
}
var hasRange = plans.some(function (p) { return p.ranges.length > 0; });
if (!hasRange) {
bibSetGlobalBatchInfo(
infoEl,
bibJs('jsGlobalNoSeq') || bibJs('jsNoSeqSelected'),
'error'
);
return Promise.resolve(null);
}
bibSetGlobalBatchInfo(infoEl, bibJs('jsLoaderWait') || '…', 'normal');
return fetch('/ajax_bib_range.php', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body:
'action=batch_global_analysis'
+ '&eve_id=' + encodeURIComponent(moduleBib.dataset.eveId || '')
+ bibAppendBatchSortParams('', sortKeys)
+ '&plans=' + encodeURIComponent(JSON.stringify(plans))
+ bibAjaxLangSuffix()
})
.then(function (res) { return res.json(); })
.then(function (data) {
if (!data.success) {
bibSetGlobalBatchInfo(
infoEl,
data.message || bibJs('jsErrGeneric'),
'error'
);
return data;
}
var state = (data.stats && data.stats.nb_manque > 0) ? 'warning' : 'normal';
bibSetGlobalBatchInfo(infoEl, data.info || '', state);
return data;
})
.catch(function () {
bibSetGlobalBatchInfo(infoEl, bibJs('jsErrGeneric'), 'error');
return null;
});
}
function bibCollectGlobalBatchGeneratedEprIds() {
var section = bibGetGlobalBatchGeneratedSection();
if (!section) {
return [];
}
var ids = [];
section.querySelectorAll('.bib-global-gen-epr-select:checked').forEach(function (cb) {
var eprId = parseInt(cb.dataset.eprId || '0', 10);
if (eprId) {
ids.push(eprId);
}
});
return ids;
}
function bibGetGlobalBatchGeneratedStartBib() {
var section = bibGetGlobalBatchGeneratedSection();
if (!section) {
return 0;
}
var inp = section.querySelector('.bib-global-gen-start-bib');
if (!inp) {
return 0;
}
return parseInt(inp.value || '0', 10) || 0;
}
function bibAppendGlobalBatchGeneratedParams(body, section) {
var sortKeys = bibGetGlobalBatchSortKeys(section);
body = bibAppendBatchSortParams(body, sortKeys);
body += '&start_bib=' + encodeURIComponent(bibGetGlobalBatchGeneratedStartBib());
body += '&epr_ids=' + encodeURIComponent(JSON.stringify(bibCollectGlobalBatchGeneratedEprIds()));
return body;
}
function updateGlobalBatchGeneratedAnalysis() {
var section = bibGetGlobalBatchGeneratedSection();
if (!section) {
return Promise.resolve();
}
var infoEl = section.querySelector('.bib-global-gen-batch__info');
var eprIds = bibCollectGlobalBatchGeneratedEprIds();
var startBib = bibGetGlobalBatchGeneratedStartBib();
if (!infoEl) {
return Promise.resolve();
}
if (eprIds.length === 0) {
bibSetGlobalBatchInfo(
infoEl,
bibJs('jsGlobalNoEpr') || bibJs('jsBatchNone'),
'error'
);
return Promise.resolve(null);
}
if (startBib <= 0) {
bibSetGlobalBatchInfo(
infoEl,
bibJs('jsGlobalGenNoStart') || bibJs('jsFieldsRequired'),
'error'
);
return Promise.resolve(null);
}
bibSetGlobalBatchInfo(infoEl, bibJs('jsLoaderWait') || '…', 'normal');
return fetch('/ajax_bib_range.php', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: bibAppendGlobalBatchGeneratedParams(
'action=batch_global_gen_analysis'
+ '&eve_id=' + encodeURIComponent(moduleBib.dataset.eveId || ''),
section
) + bibAjaxLangSuffix()
})
.then(function (res) { return res.json(); })
.then(function (data) {
if (!data.success) {
bibSetGlobalBatchInfo(
infoEl,
data.message || bibJs('jsErrGeneric'),
'error'
);
return data;
}
bibSetGlobalBatchInfo(infoEl, data.info || '', 'normal');
return data;
})
.catch(function () {
bibSetGlobalBatchInfo(infoEl, bibJs('jsErrGeneric'), 'error');
return null;
});
}
function bibRunGlobalBatchGeneratedGo() {
var section = bibGetGlobalBatchGeneratedSection();
if (!section) {
return;
}
var eprIds = bibCollectGlobalBatchGeneratedEprIds();
var startBib = bibGetGlobalBatchGeneratedStartBib();
var sortKeys = bibGetGlobalBatchSortKeys(section);
if (eprIds.length === 0) {
alert(bibJs('jsGlobalNoEpr') || bibJs('jsBatchNone'));
return;
}
if (startBib <= 0) {
alert(bibJs('jsGlobalGenNoStart') || bibJs('jsFieldsRequired'));
return;
}
fetch('/ajax_bib_range.php', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: bibAppendGlobalBatchGeneratedParams(
'action=batch_global_gen_create'
+ '&eve_id=' + encodeURIComponent(moduleBib.dataset.eveId || ''),
section
) + bibAjaxLangSuffix()
})
.then(function (res) {
if (!res.ok) {
throw new Error(bibJs('jsErrGeneric') || 'Erreur');
}
return res.json().catch(function () {
throw new Error(bibJs('jsServerError') || bibJs('jsErrGeneric') || 'Erreur serveur');
});
})
.then(function (createData) {
if (!createData || !createData.success || !Array.isArray(createData.plans) || createData.plans.length === 0) {
throw new Error((createData && createData.message) || bibJs('jsErrGeneric') || 'Erreur');
}
var plans = createData.plans;
var globalTotal = (createData.stats && createData.stats.nb_participants)
? createData.stats.nb_participants
: 1;
var completedOffset = 0;
var runResults = [];
bibBatchProgressShow(0, globalTotal);
var chain = Promise.resolve();
plans.forEach(function (plan) {
chain = chain.then(function () {
var row = moduleBib.querySelector('.epr-row[data-epr-id="' + plan.epr_id + '"]');
if (!row) {
throw new Error(
bibJs('jsGlobalGenEprMissing')
|| bibJs('jsErrGeneric')
|| 'Épreuve introuvable — rechargez la page.'
);
}
var pendingBefore = bibRowPendingBibs(row);
var offset = completedOffset;
return bibRunBatchApplyChunks(row, plan.ranges, sortKeys, {
showResult: false,
manageLoader: false,
deferUiRefresh: true,
totalInitial: pendingBefore,
onProgress: function (processed) {
bibBatchProgressShow(offset + processed, globalTotal);
}
}).then(function (data) {
runResults.push({
epr_id: plan.epr_id,
assigned: data.assigned_total || 0,
total: data.total_initial || pendingBefore
});
completedOffset = offset + pendingBefore;
});
});
});
return chain.then(function () {
bibBatchProgressShow(
globalTotal,
globalTotal,
bibJs('jsGlobalBatchFinalizing') || bibJs('jsLoaderWait')
);
var refreshChain = Promise.resolve();
runResults.forEach(function (result) {
refreshChain = refreshChain.then(function () {
var row = moduleBib.querySelector('.epr-row[data-epr-id="' + result.epr_id + '"]');
if (!row) {
return null;
}
return bibAfterBatchGoRefreshOnly(row, false, {
loader: false,
skipAnomalies: true
});
});
});
return refreshChain.then(function () {
if (typeof refreshBibAnomaliesPanel === 'function') {
return refreshBibAnomaliesPanel();
}
}).then(function () {
bibFinishGlobalBatchGo(runResults);
});
});
})
.catch(function (err) {
alert(err.message || bibJs('jsErrGeneric'));
})
.finally(function () {
bibBatchProgressForceHide();
});
}
// MSIN-4445 — Assignation libre (Début / Qté / Fin, sans séquence).
function bibCollectGlobalBatchFreeEprIds() {
var section = bibGetGlobalBatchFreeSection();
if (!section) {
return [];
}
var ids = [];
section.querySelectorAll('.bib-global-free-epr-select:checked').forEach(function (cb) {
var eprId = parseInt(cb.dataset.eprId || '0', 10);
if (eprId) {
ids.push(eprId);
}
});
return ids;
}
function bibCollectGlobalBatchFreePending() {
var section = bibGetGlobalBatchFreeSection();
if (!section) {
return 0;
}
var total = 0;
section.querySelectorAll('.bib-global-free-epr-select:checked').forEach(function (cb) {
var block = cb.closest('.bib-global-epr');
var pending = block
? parseInt(block.dataset.pending || '0', 10)
: 0;
if (pending > 0) {
total += pending;
}
});
return total;
}
function bibGetGlobalBatchFreeRangeFields(section) {
section = section || bibGetGlobalBatchFreeSection();
if (!section) {
return null;
}
var wrap = section.querySelector('.bib-global-free-range');
if (!wrap) {
return null;
}
return {
wrap: wrap,
start: wrap.querySelector('.bib-global-free-start'),
qty: wrap.querySelector('.bib-global-free-qty'),
end: wrap.querySelector('.bib-global-free-end'),
feedback: wrap.querySelector('.bib-global-free-range__feedback'),
qtyEl: wrap.querySelector('.bib-global-free-range__qty'),
dupesEl: wrap.querySelector('.bib-global-free-range__dupes')
};
}
function bibGetGlobalBatchFreeBounds(section) {
var fields = bibGetGlobalBatchFreeRangeFields(section);
if (!fields) {
return { start: 0, end: 0, qty: 0 };
}
var start = bibRangeParseInt(fields.start && fields.start.value);
var qty = bibRangeParseInt(fields.qty && fields.qty.value);
var end = bibRangeParseInt(fields.end && fields.end.value);
var pilot = (fields.wrap && fields.wrap.dataset.rangePilot) || '';
if (start > 0 && pilot === 'qty' && qty > 0) {
end = start + qty - 1;
} else if (start > 0 && pilot === 'end' && end >= start) {
qty = end - start + 1;
} else if (start > 0 && end >= start) {
qty = end - start + 1;
} else {
qty = 0;
if (end < start) {
end = 0;
}
}
return { start: start, end: end, qty: qty };
}
function bibFormatGlobalFreeQtyFeedback(qty, pending) {
var diff = qty - pending;
if (qty <= 0) {
return '';
}
if (diff === 0) {
return bibJs('jsGlobalFreeQtyJuste') || 'Quantité juste';
}
if (diff > 0) {
return bibJsFmt('jsGlobalFreeQtySupplementaire', diff)
|| (('Quantité supplémentaire : %d').replace('%d', String(diff)));
}
return bibJsFmt('jsGlobalFreeQtyManquante', Math.abs(diff))
|| (('Quantité manquante : %d').replace('%d', String(Math.abs(diff))));
}
function bibSetGlobalFreeDupesWarn(section, blnShow, strMessage) {
var fields = bibGetGlobalBatchFreeRangeFields(section);
if (!fields) {
return;
}
var msg = strMessage
|| bibJs('jsGlobalFreeDupesWarn')
|| 'Attention : vous êtes en train de créer des inscriptions avec des dossards en double.';
if (fields.dupesEl) {
if (!blnShow) {
fields.dupesEl.textContent = '';
fields.dupesEl.classList.add('bib-ui-hidden');
} else {
fields.dupesEl.textContent = msg;
fields.dupesEl.classList.remove('bib-ui-hidden');
}
return;
}
// Repli si l'ancien markup n'a pas la ligne dédiée.
if (fields.feedback && blnShow) {
var base = (fields.qtyEl && fields.qtyEl.textContent)
? fields.qtyEl.textContent
: (fields.feedback.textContent || '');
fields.feedback.textContent = base
? (base + ' — ' + msg)
: msg;
}
}
function bibUpdateGlobalFreeQtyFeedback(section) {
var fields = bibGetGlobalBatchFreeRangeFields(section);
if (!fields) {
return;
}
var bounds = bibGetGlobalBatchFreeBounds(section);
var pending = bibCollectGlobalBatchFreePending();
var msg = bibFormatGlobalFreeQtyFeedback(bounds.qty, pending);
var qtyEl = fields.qtyEl || fields.feedback;
if (qtyEl) {
qtyEl.textContent = msg;
qtyEl.classList.remove(
'bib-global-free-range__feedback--juste',
'bib-global-free-range__feedback--manquante',
'bib-global-free-range__feedback--supplementaire'
);
if (msg) {
if (bounds.qty === pending) {
qtyEl.classList.add('bib-global-free-range__feedback--juste');
} else if (bounds.qty < pending) {
qtyEl.classList.add('bib-global-free-range__feedback--manquante');
} else {
qtyEl.classList.add('bib-global-free-range__feedback--supplementaire');
}
}
}
if (!msg) {
bibSetGlobalFreeDupesWarn(section, false);
}
}
function bibSyncGlobalFreeRangeDerived(section) {
var fields = bibGetGlobalBatchFreeRangeFields(section);
if (!fields) {
return;
}
var start = bibRangeParseInt(fields.start && fields.start.value);
var pilot = (fields.wrap && fields.wrap.dataset.rangePilot) || '';
if (start <= 0) {
if (fields.qty) {
fields.qty.value = '';
fields.qty.disabled = true;
fields.qty.classList.remove('bib-field--active', 'bib-field--calc', 'bib-field--pick');
fields.qty.classList.add('bib-field--idle');
}
if (fields.end) {
fields.end.value = '';
fields.end.disabled = true;
fields.end.classList.remove('bib-field--active', 'bib-field--calc', 'bib-field--pick');
fields.end.classList.add('bib-field--idle');
}
if (fields.wrap) {
fields.wrap.dataset.rangePilot = '';
}
bibUpdateGlobalFreeQtyFeedback(section);
return;
}
if (!pilot) {
if (fields.qty) {
fields.qty.disabled = false;
fields.qty.classList.remove('bib-field--idle', 'bib-field--active', 'bib-field--calc');
fields.qty.classList.add('bib-field--pick');
}
if (fields.end) {
fields.end.disabled = false;
fields.end.classList.remove('bib-field--idle', 'bib-field--active', 'bib-field--calc');
fields.end.classList.add('bib-field--pick');
}
bibUpdateGlobalFreeQtyFeedback(section);
return;
}
if (pilot === 'qty') {
var qty = bibRangeParseInt(fields.qty && fields.qty.value);
if (fields.end) {
fields.end.disabled = true;
fields.end.classList.remove('bib-field--active', 'bib-field--pick', 'bib-field--idle');
fields.end.classList.add('bib-field--calc');
fields.end.value = qty > 0 ? String(start + qty - 1) : '';
}
if (fields.qty) {
fields.qty.disabled = false;
fields.qty.classList.remove('bib-field--idle', 'bib-field--calc', 'bib-field--pick');
fields.qty.classList.add('bib-field--active');
}
} else if (pilot === 'end') {
var end = bibRangeParseInt(fields.end && fields.end.value);
if (fields.qty) {
fields.qty.disabled = true;
fields.qty.classList.remove('bib-field--active', 'bib-field--pick', 'bib-field--idle');
fields.qty.classList.add('bib-field--calc');
fields.qty.value = (end >= start) ? String(end - start + 1) : '';
}
if (fields.end) {
fields.end.disabled = false;
fields.end.classList.remove('bib-field--idle', 'bib-field--calc', 'bib-field--pick');
fields.end.classList.add('bib-field--active');
}
}
bibUpdateGlobalFreeQtyFeedback(section);
}
function bibPickGlobalFreePilot(section, pilot) {
var fields = bibGetGlobalBatchFreeRangeFields(section);
if (!fields || !fields.wrap) {
return;
}
var start = bibRangeParseInt(fields.start && fields.start.value);
if (start <= 0) {
return;
}
fields.wrap.dataset.rangePilot = pilot;
bibSyncGlobalFreeRangeDerived(section);
var target = pilot === 'qty' ? fields.qty : fields.end;
if (target && !target.disabled) {
target.focus();
}
}
function bibBindGlobalFreeRange(section) {
var fields = bibGetGlobalBatchFreeRangeFields(section);
if (!fields || !fields.wrap || fields.wrap.dataset.bound === '1') {
return;
}
fields.wrap.dataset.bound = '1';
if (fields.start) {
fields.start.addEventListener('input', function () {
bibSyncGlobalFreeRangeDerived(section);
updateGlobalBatchFreeAnalysis();
});
}
if (fields.qty) {
fields.qty.addEventListener('focus', function () {
bibPickGlobalFreePilot(section, 'qty');
});
fields.qty.addEventListener('click', function () {
bibPickGlobalFreePilot(section, 'qty');
});
fields.qty.addEventListener('input', function () {
if (fields.wrap.dataset.rangePilot !== 'qty') {
fields.wrap.dataset.rangePilot = 'qty';
}
bibSyncGlobalFreeRangeDerived(section);
updateGlobalBatchFreeAnalysis();
});
}
if (fields.end) {
fields.end.addEventListener('focus', function () {
bibPickGlobalFreePilot(section, 'end');
});
fields.end.addEventListener('click', function () {
bibPickGlobalFreePilot(section, 'end');
});
fields.end.addEventListener('input', function () {
if (fields.wrap.dataset.rangePilot !== 'end') {
fields.wrap.dataset.rangePilot = 'end';
}
bibSyncGlobalFreeRangeDerived(section);
updateGlobalBatchFreeAnalysis();
});
}
bibSyncGlobalFreeRangeDerived(section);
}
function bibAppendGlobalBatchFreeParams(body, section) {
var sortKeys = bibGetGlobalBatchSortKeys(section);
var bounds = bibGetGlobalBatchFreeBounds(section);
body = bibAppendBatchSortParams(body, sortKeys);
body += '&start_bib=' + encodeURIComponent(bounds.start);
body += '&end_bib=' + encodeURIComponent(bounds.end);
body += '&epr_ids=' + encodeURIComponent(JSON.stringify(bibCollectGlobalBatchFreeEprIds()));
return body;
}
function updateGlobalBatchFreeAnalysis() {
var section = bibGetGlobalBatchFreeSection();
if (!section) {
return Promise.resolve();
}
bibBindGlobalFreeRange(section);
var infoEl = section.querySelector('.bib-global-free-batch__info');
var eprIds = bibCollectGlobalBatchFreeEprIds();
var bounds = bibGetGlobalBatchFreeBounds(section);
bibUpdateGlobalFreeQtyFeedback(section);
if (!infoEl) {
return Promise.resolve();
}
if (eprIds.length === 0) {
bibSetGlobalBatchInfo(
infoEl,
bibJs('jsGlobalNoEpr') || bibJs('jsBatchNone'),
'error'
);
bibSetGlobalFreeDupesWarn(section, false);
return Promise.resolve(null);
}
if (bounds.start <= 0 || bounds.end < bounds.start) {
bibSetGlobalBatchInfo(
infoEl,
bibJs('jsGlobalFreePlanInvalid') || bibJs('jsFieldsRequired'),
'error'
);
bibSetGlobalFreeDupesWarn(section, false);
return Promise.resolve(null);
}
bibSetGlobalBatchInfo(infoEl, bibJs('jsLoaderWait') || '…', 'normal');
return fetch('/ajax_bib_range.php', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: bibAppendGlobalBatchFreeParams(
'action=batch_global_free_analysis'
+ '&eve_id=' + encodeURIComponent(moduleBib.dataset.eveId || ''),
section
) + bibAjaxLangSuffix()
})
.then(function (res) { return res.json(); })
.then(function (data) {
if (!data.success) {
bibSetGlobalBatchInfo(
infoEl,
data.message || bibJs('jsErrGeneric'),
'error'
);
bibSetGlobalFreeDupesWarn(section, false);
return data;
}
var state = 'normal';
if (data.feedback && data.feedback.status === 'manquante') {
state = 'warning';
}
if (data.duplicates && data.duplicates.has) {
state = 'warning';
}
bibSetGlobalBatchInfo(infoEl, data.info || '', state);
bibUpdateGlobalFreeQtyFeedback(section);
bibSetGlobalFreeDupesWarn(
section,
!!(data.duplicates && data.duplicates.has),
(data.duplicates && data.duplicates.message) || ''
);
return data;
})
.catch(function () {
bibSetGlobalBatchInfo(infoEl, bibJs('jsErrGeneric'), 'error');
bibSetGlobalFreeDupesWarn(section, false);
return null;
});
}
function bibFetchBatchApplyFreeChunk(row, plan, sortKeys, opts) {
opts = opts || {};
sortKeys = sortKeys || bibGetRowSortKeys(row);
var body =
'action=batch_apply_free_chunk'
+ '&epr_id=' + encodeURIComponent(row.dataset.eprId)
+ '&eve_id=' + encodeURIComponent(moduleBib.dataset.eveId || '')
+ '&start_bib=' + encodeURIComponent(plan.start || 0)
+ '&end_bib=' + encodeURIComponent(plan.end || 0)
+ bibAppendBatchSortParams('', sortKeys)
+ '&chunk_size=' + BIB_BATCH_CHUNK_SIZE
+ '&total_initial=' + (opts.totalInitial || 0)
+ '&batch_reset=' + (opts.batchReset ? 1 : 0)
+ bibAjaxLangSuffix();
return fetch('/ajax_bib_range.php', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: body
})
.then(function (res) {
if (!res.ok) {
throw new Error(bibJs('jsErrGeneric'));
}
return res.json();
});
}
function bibRunBatchApplyFreeChunks(row, plan, sortKeys, options) {
options = options || {};
var manageLoader = options.manageLoader !== false;
var onProgress = options.onProgress;
var totalInitial = options.totalInitial > 0
? options.totalInitial
: bibRowPendingBibs(row);
var batchReset = true;
var chunkGuard = 0;
var lastData = null;
function runNext() {
chunkGuard += 1;
if (chunkGuard > 500) {
return Promise.reject(new Error(bibJs('jsErrGeneric')));
}
return bibFetchBatchApplyFreeChunk(row, plan, sortKeys, {
totalInitial: totalInitial,
batchReset: batchReset
}).then(function (data) {
batchReset = false;
lastData = data;
if (!data || !data.success) {
throw new Error((data && data.message) || bibJs('jsErrGeneric'));
}
if (typeof onProgress === 'function') {
onProgress(data.processed || 0);
}
if (data.complete) {
return data;
}
return runNext();
});
}
if (manageLoader) {
bibBatchProgressShow(0, totalInitial);
}
return runNext().then(function (data) {
return data || lastData || { success: true, assigned_total: 0, total_initial: totalInitial };
});
}
function bibRunGlobalBatchFreeGo() {
var section = bibGetGlobalBatchFreeSection();
if (!section) {
return;
}
var eprIds = bibCollectGlobalBatchFreeEprIds();
var bounds = bibGetGlobalBatchFreeBounds(section);
var sortKeys = bibGetGlobalBatchSortKeys(section);
if (eprIds.length === 0) {
alert(bibJs('jsGlobalNoEpr') || bibJs('jsBatchNone'));
return;
}
if (bounds.start <= 0 || bounds.end < bounds.start) {
alert(bibJs('jsGlobalFreePlanInvalid') || bibJs('jsFieldsRequired'));
return;
}
fetch('/ajax_bib_range.php', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: bibAppendGlobalBatchFreeParams(
'action=batch_global_free_plan'
+ '&eve_id=' + encodeURIComponent(moduleBib.dataset.eveId || ''),
section
) + bibAjaxLangSuffix()
})
.then(function (res) {
if (!res.ok) {
throw new Error(bibJs('jsErrGeneric') || 'Erreur');
}
return res.json().catch(function () {
throw new Error(bibJs('jsServerError') || bibJs('jsErrGeneric') || 'Erreur serveur');
});
})
.then(function (planData) {
if (!planData || !planData.success || !Array.isArray(planData.plans) || planData.plans.length === 0) {
throw new Error((planData && planData.message) || bibJs('jsErrGeneric') || 'Erreur');
}
var plans = planData.plans;
var globalTotal = (planData.stats && planData.stats.nb_participants)
? planData.stats.nb_participants
: 1;
var completedOffset = 0;
var runResults = [];
bibBatchProgressShow(0, globalTotal);
var chain = Promise.resolve();
plans.forEach(function (plan) {
chain = chain.then(function () {
var row = moduleBib.querySelector('.epr-row[data-epr-id="' + plan.epr_id + '"]');
if (!row) {
throw new Error(
bibJs('jsGlobalGenEprMissing')
|| bibJs('jsErrGeneric')
|| 'Épreuve introuvable — rechargez la page.'
);
}
var pendingBefore = bibRowPendingBibs(row);
var offset = completedOffset;
return bibRunBatchApplyFreeChunks(row, plan, sortKeys, {
manageLoader: false,
totalInitial: pendingBefore,
onProgress: function (processed) {
bibBatchProgressShow(offset + processed, globalTotal);
}
}).then(function (data) {
runResults.push({
epr_id: plan.epr_id,
assigned: data.assigned_total || 0,
total: data.total_initial || pendingBefore
});
completedOffset = offset + pendingBefore;
});
});
});
return chain.then(function () {
bibBatchProgressShow(
globalTotal,
globalTotal,
bibJs('jsGlobalBatchFinalizing') || bibJs('jsLoaderWait')
);
var refreshChain = Promise.resolve();
runResults.forEach(function (result) {
refreshChain = refreshChain.then(function () {
var row = moduleBib.querySelector('.epr-row[data-epr-id="' + result.epr_id + '"]');
if (!row) {
return null;
}
return bibAfterBatchGoRefreshOnly(row, false, {
loader: false,
skipAnomalies: true
});
});
});
return refreshChain.then(function () {
if (typeof refreshBibAnomaliesPanel === 'function') {
return refreshBibAnomaliesPanel();
}
}).then(function () {
bibInvalidateGlobalBatchPanel();
bibFinishGlobalBatchGo(runResults);
});
});
})
.catch(function (err) {
alert(err.message || bibJs('jsErrGeneric'));
})
.finally(function () {
bibBatchProgressForceHide();
});
}
function bibRunGlobalBatchGo() {
var section = bibGetGlobalBatchExistingSection();
if (!section) {
return;
}
var plans = bibCollectGlobalBatchPlans();
var sortKeys = bibGetGlobalBatchSortKeys(section);
if (plans.length === 0) {
alert(bibJs('jsGlobalNoEpr') || bibJs('jsBatchNone'));
return;
}
if (!plans.some(function (p) { return p.ranges.length > 0; })) {
alert(bibJs('jsGlobalNoSeq') || bibJs('jsNoSeqSelected'));
return;
}
fetch('/ajax_bib_range.php', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body:
'action=batch_global_analysis'
+ '&eve_id=' + encodeURIComponent(moduleBib.dataset.eveId || '')
+ bibAppendBatchSortParams('', sortKeys)
+ '&plans=' + encodeURIComponent(JSON.stringify(plans))
+ bibAjaxLangSuffix()
})
.then(function (res) {
if (!res.ok) {
throw new Error(bibJs('jsErrGeneric'));
}
return res.json();
})
.then(function (analysis) {
if (!analysis || !analysis.success) {
throw new Error((analysis && analysis.message) || bibJs('jsErrGeneric'));
}
var globalTotal = (analysis.stats && analysis.stats.nb_participants)
? analysis.stats.nb_participants
: 1;
var completedOffset = 0;
var runResults = [];
bibBatchProgressShow(0, globalTotal);
var chain = Promise.resolve();
plans.forEach(function (plan) {
chain = chain.then(function () {
var row = moduleBib.querySelector('.epr-row[data-epr-id="' + plan.epr_id + '"]');
if (!row) {
throw new Error(bibJs('jsErrGeneric'));
}
var pendingBefore = bibRowPendingBibs(row);
var offset = completedOffset;
return bibRunBatchApplyChunks(row, plan.ranges, sortKeys, {
showResult: false,
manageLoader: false,
deferUiRefresh: true,
totalInitial: pendingBefore,
onProgress: function (processed) {
bibBatchProgressShow(offset + processed, globalTotal);
}
}).then(function (data) {
runResults.push({
epr_id: plan.epr_id,
assigned: data.assigned_total || 0,
total: data.total_initial || pendingBefore
});
completedOffset = offset + pendingBefore;
});
});
});
return chain.then(function () {
bibBatchProgressShow(
globalTotal,
globalTotal,
bibJs('jsGlobalBatchFinalizing') || bibJs('jsLoaderWait')
);
var refreshChain = Promise.resolve();
runResults.forEach(function (result) {
refreshChain = refreshChain.then(function () {
var row = moduleBib.querySelector('.epr-row[data-epr-id="' + result.epr_id + '"]');
if (!row) {
return null;
}
return bibAfterBatchGoRefreshOnly(row, false, {
loader: false,
skipAnomalies: true
});
});
});
return refreshChain.then(function () {
if (typeof refreshBibAnomaliesPanel === 'function') {
return refreshBibAnomaliesPanel();
}
}).then(function () {
bibFinishGlobalBatchGo(runResults);
});
});
})
.catch(function (err) {
alert(err.message || bibJs('jsErrGeneric'));
})
.finally(function () {
bibBatchProgressForceHide();
});
}
moduleBib.addEventListener('keydown', function (e) {
if (e.key !== 'Enter' && e.key !== ' ') {
return;
}
var workspaceTab = e.target.closest('.bib-workspace-tab[role="tab"]');
if (workspaceTab && moduleBib.contains(workspaceTab)) {
e.preventDefault();
bibSetWorkspace(workspaceTab.getAttribute('data-bib-workspace'));
return;
}
var toolBtn = e.target.closest('.bib-tool-btn[role="button"]');
if (!toolBtn || !moduleBib.contains(toolBtn)) {
return;
}
e.preventDefault();
bibOpenTool(toolBtn.getAttribute('data-bib-tool'));
});
moduleBib.addEventListener('click', function (e) {
var workspaceTab = e.target.closest('.bib-workspace-tab');
if (workspaceTab && moduleBib.contains(workspaceTab)) {
if (e.target.closest('.btn-aide-trad, .btn-trad-admin, .ms1-trad-link')) {
return;
}
e.preventDefault();
bibSetWorkspace(workspaceTab.getAttribute('data-bib-workspace'));
return;
}
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();
return;
}
var toolBtn = e.target.closest('.bib-tool-btn');
if (toolBtn && moduleBib.contains(toolBtn)) {
if (e.target.closest('.btn-aide-bib, .bib-aide-trigger, .btn-aide-trad, .btn-doc-trigger, .btn-admin-doc, .btn-trad-admin')) {
return;
}
e.preventDefault();
bibOpenTool(toolBtn.getAttribute('data-bib-tool'));
return;
}
if (e.target.closest('.btn-simuler-global-batch')) {
e.preventDefault();
var existingSection = bibGetGlobalBatchExistingSection();
var plans = bibCollectGlobalBatchPlans();
var sortKeys = existingSection
? bibGetGlobalBatchSortKeys(existingSection)
: { sort1: '', sort2: '' };
if (plans.length === 0) {
alert(bibJs('jsGlobalNoEpr') || bibJs('jsBatchNone'));
return;
}
bibFetch('/ajax_bib_range.php', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body:
'action=batch_global_simulate'
+ '&eve_id=' + encodeURIComponent(moduleBib.dataset.eveId || '')
+ bibAppendBatchSortParams('', sortKeys)
+ '&plans=' + encodeURIComponent(JSON.stringify(plans))
+ bibAjaxLangSuffix()
})
.then(function (res) { return res.json(); })
.then(function (data) {
if (!data.success) {
alert(data.message || bibJs('jsErrGeneric'));
return;
}
bibInsertGlobalSimView(data.html);
});
return;
}
if (e.target.closest('.btn-simuler-global-gen-batch')) {
e.preventDefault();
var genSection = bibGetGlobalBatchGeneratedSection();
var eprIds = bibCollectGlobalBatchGeneratedEprIds();
var startBib = bibGetGlobalBatchGeneratedStartBib();
if (eprIds.length === 0) {
alert(bibJs('jsGlobalNoEpr') || bibJs('jsBatchNone'));
return;
}
if (startBib <= 0) {
alert(bibJs('jsGlobalGenNoStart') || bibJs('jsFieldsRequired'));
return;
}
bibFetch('/ajax_bib_range.php', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: bibAppendGlobalBatchGeneratedParams(
'action=batch_global_gen_simulate'
+ '&eve_id=' + encodeURIComponent(moduleBib.dataset.eveId || ''),
genSection
) + bibAjaxLangSuffix()
})
.then(function (res) { return res.json(); })
.then(function (data) {
if (!data.success) {
alert(data.message || bibJs('jsErrGeneric'));
return;
}
bibInsertGlobalSimView(data.html);
});
return;
}
if (e.target.closest('.btn-go-global-batch')) {
e.preventDefault();
bibRunGlobalBatchGo();
return;
}
if (e.target.closest('.btn-go-global-gen-batch')) {
e.preventDefault();
bibRunGlobalBatchGeneratedGo();
return;
}
if (e.target.closest('.btn-simuler-global-free-batch')) {
e.preventDefault();
var freeSection = bibGetGlobalBatchFreeSection();
var freeEprIds = bibCollectGlobalBatchFreeEprIds();
var freeBounds = bibGetGlobalBatchFreeBounds(freeSection);
if (freeEprIds.length === 0) {
alert(bibJs('jsGlobalNoEpr') || bibJs('jsBatchNone'));
return;
}
if (freeBounds.start <= 0 || freeBounds.end < freeBounds.start) {
alert(bibJs('jsGlobalFreePlanInvalid') || bibJs('jsFieldsRequired'));
return;
}
bibFetch('/ajax_bib_range.php', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: bibAppendGlobalBatchFreeParams(
'action=batch_global_free_simulate'
+ '&eve_id=' + encodeURIComponent(moduleBib.dataset.eveId || ''),
freeSection
) + bibAjaxLangSuffix()
})
.then(function (res) { return res.json(); })
.then(function (data) {
if (!data.success) {
alert(data.message || bibJs('jsErrGeneric'));
return;
}
bibInsertGlobalSimView(data.html);
});
return;
}
if (e.target.closest('.btn-go-global-free-batch')) {
e.preventDefault();
bibRunGlobalBatchFreeGo();
}
});
moduleBib.addEventListener('change', function (e) {
if (!e.target.matches(
'.bib-global-epr-select, .bib-global-range-select, .bib-global-batch-order, .bib-global-batch-order-2,'
+ ' .bib-global-gen-epr-select, .bib-global-gen-batch-order, .bib-global-gen-batch-order-2, .bib-global-gen-start-bib,'
+ ' .bib-global-free-epr-select, .bib-global-free-batch-order, .bib-global-free-batch-order-2,'
+ ' .bib-global-free-start, .bib-global-free-qty, .bib-global-free-end'
)) {
return;
}
var bibGlobalBatchPanel = bibGetGlobalBatchBody();
if (!bibGlobalBatchPanel || !bibGlobalBatchPanel.contains(e.target)) {
return;
}
if (e.target.closest('.bib-global-batch--existing')) {
var eprBlock = e.target.closest('.bib-global-epr');
if (eprBlock && e.target.classList.contains('bib-global-epr-select')) {
var checked = e.target.checked;
eprBlock.querySelectorAll('.bib-global-range-select').forEach(function (cb) {
cb.disabled = !checked;
if (!checked) {
cb.checked = false;
}
});
}
updateGlobalBatchAnalysis();
return;
}
if (e.target.closest('.bib-global-batch--generated')) {
updateGlobalBatchGeneratedAnalysis();
return;
}
if (e.target.closest('.bib-global-batch--free')) {
updateGlobalBatchFreeAnalysis();
}
});
function bibRowPendingBibs(row) {
if (!row) return 0;
return parseInt(row.dataset.bibAAssigner || '0', 10) || 0;
}
function bibRefreshPreparationOverview() {
var rows = Array.from(moduleBib.querySelectorAll('.epr-row[data-epr-id]'));
var total = 0;
var assigned = 0;
var pending = 0;
rows.forEach(function (raceRow) {
total += parseInt((raceRow.querySelector('.bib-race-summary-total') || {}).textContent || '0', 10) || 0;
assigned += parseInt((raceRow.querySelector('.bib-race-summary-assigned') || {}).textContent || '0', 10) || 0;
pending += parseInt((raceRow.querySelector('.bib-race-summary-pending') || {}).textContent || '0', 10) || 0;
});
var values = {
bib_v5_stat_races: rows.length,
bib_v5_stat_registered: total,
bib_v5_stat_assigned: assigned,
bib_v5_stat_pending: pending
};
Object.keys(values).forEach(function (key) {
var el = moduleBib.querySelector('[data-bib-overview-stat="' + key + '"]');
if (el) {
el.textContent = values[key];
}
});
}
function bibSyncRaceSummaryStatus(row) {
if (!row) return;
bibRefreshPreparationOverview();
}
function bibSyncEprBibStats(row, info) {
if (!row || !info) return;
if (info.total !== undefined) {
let totalEl = row.querySelector('.bib-total');
if (totalEl) totalEl.textContent = info.total;
let summaryTotal = row.querySelector('.bib-race-summary-total');
if (summaryTotal) summaryTotal.textContent = info.total;
}
if (info.avec_bib !== undefined) {
let avecEl = row.querySelector('.bib-avec');
if (avecEl) avecEl.textContent = info.avec_bib;
let summaryAssigned = row.querySelector('.bib-race-summary-assigned');
if (summaryAssigned) summaryAssigned.textContent = info.avec_bib;
}
let pending = (info.a_assigner !== undefined && info.a_assigner !== null)
? info.a_assigner
: (info.sans_bib || 0);
row.dataset.bibAAssigner = String(parseInt(pending, 10) || 0);
let summaryPending = row.querySelector('.bib-race-summary-pending');
if (summaryPending) summaryPending.textContent = parseInt(pending, 10) || 0;
bibSyncRaceSummaryStatus(row);
}
function bibAlertAutoPendingBibs(row) {
alert(bibJsFmt('jsAutoPendingBibs', bibRowPendingBibs(row)).replace(/\\n/g, '\n'));
}
/** Bloque l'entrée en mode auto si des inscriptions n'ont pas encore de dossard. */
function bibBlockAutoActivation(row) {
if (!row || row.dataset.autoActive === '1') {
return false;
}
if (bibRowPendingBibs(row) > 0) {
bibAlertAutoPendingBibs(row);
return true;
}
return false;
}
// MSIN-4379 — Mise à jour affichage quantités (panneau gestion + pastille en-tête).
function bibApplyQteData(data) {
if (!data || typeof data !== 'object') {
return;
}
Object.keys(data).forEach(function (eprId) {
if (eprId === 'total') {
return;
}
let row = data[eprId];
if (!row) {
return;
}
let elOrigine = document.getElementById('qte_origine_' + eprId);
let elAjustement = document.getElementById('qte_ajustement_' + eprId);
let elCourante = document.getElementById('qte_courante_' + eprId);
let elInscrits = document.getElementById('qte_inscrits_' + eprId);
let elCheckin = document.getElementById('qte_checkin_' + eprId);
let elRestante = document.getElementById('qte_restante_' + eprId);
if (elOrigine) {
elOrigine.textContent = row.qte_origine;
}
if (elAjustement) {
elAjustement.textContent = row.qte_ajustement;
}
if (elCourante) {
elCourante.textContent = row.qte_courante;
}
if (elInscrits) {
elInscrits.textContent = row.qte_inscrits;
}
if (elCheckin) {
elCheckin.textContent = row.qte_checkin;
}
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'
);
if (dispoBadge && row.qte_restante !== undefined) {
let labelParts = dispoBadge.textContent.split(':');
let label = labelParts.length > 1 ? labelParts[0].trim() : '';
dispoBadge.textContent = label + ' : ' + row.qte_restante;
}
let btnQte = document.querySelector(
'.epr-gestion-panel[data-epr-id="' + eprId + '"] .btn_qte'
);
if (btnQte) {
btnQte.setAttribute('data-qte_initiale', row.qte_restante);
}
});
}
function bibSaveQte(btn) {
let eprId = btn.getAttribute('data-epr_id');
if (!eprId) {
return;
}
let input = document.getElementById('qte_restante_' + eprId);
if (!input) {
return;
}
let intQte = parseInt(input.value, 10);
if (isNaN(intQte) || intQte < 0) {
alert(bibJs('err-generic'));
return;
}
bibLoaderShow();
fetch('/ajax_promoteur.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
credentials: 'same-origin',
body:
'a=qte'
+ '&epr_id=' + encodeURIComponent(eprId)
+ '&qte=' + encodeURIComponent(intQte)
+ '&lang=' + encodeURIComponent(moduleBib.dataset.lang || 'fr')
})
.then(function (res) {
return res.json();
})
.then(function (result) {
if (result && result.state === 'success' && result.data) {
bibApplyQteData(result.data);
return;
}
alert(bibJs('err-generic'));
})
.catch(function () {
alert(bibJs('server-error'));
})
.finally(function () {
bibLoaderHide();
});
}
// MSIN-4379 — Réduire / développer les blocs gestion, assignation et sections anomalies.
function bibSetRaceRowExpanded(row, expanded) {
if (!row) {
return;
}
row.classList.toggle('is-expanded', expanded);
var summary = row.querySelector('.bib-race-summary');
var button = row.querySelector('.bib-race-toggle');
if (summary) {
summary.setAttribute('aria-expanded', expanded ? 'true' : 'false');
}
if (button) {
var label = button.getAttribute(expanded ? 'data-label-collapse' : 'data-label-expand') || '';
if (label) {
button.setAttribute('aria-label', label);
button.setAttribute('title', label);
}
var icon = button.querySelector('.fa');
if (icon) {
icon.classList.toggle('fa-chevron-up', expanded);
icon.classList.toggle('fa-chevron-down', !expanded);
}
}
}
function bibToggleRaceRow(row) {
if (!row) {
return;
}
var willExpand = !row.classList.contains('is-expanded');
if (willExpand) {
moduleBib.querySelectorAll('.epr-row.is-expanded').forEach(function (otherRow) {
if (otherRow !== row) {
bibSetRaceRowExpanded(otherRow, false);
}
});
}
bibSetRaceRowExpanded(row, willExpand);
}
function bibToggleCollapsibleBlock(block, btnToggle) {
if (!block || !btnToggle) {
return;
}
let collapsed = block.classList.toggle('is-collapsed');
btnToggle.setAttribute('aria-expanded', collapsed ? 'false' : 'true');
let hdr = block.querySelector('.bib-anomaly-block-header')
|| block.querySelector('.bib-global-batch__section-header');
if (hdr) {
hdr.setAttribute('aria-expanded', collapsed ? 'false' : 'true');
}
let label = collapsed
? (btnToggle.getAttribute('data-label-expand') || '')
: (btnToggle.getAttribute('data-label-collapse') || '');
if (label) {
btnToggle.setAttribute('aria-label', label);
btnToggle.setAttribute('title', label);
}
let icon = btnToggle.querySelector('.fa');
if (icon) {
icon.classList.toggle('fa-chevron-up', !collapsed);
icon.classList.toggle('fa-chevron-down', collapsed);
}
}
/** MSIN-4467 — Accordéon du détail : au plus un panneau ouvert, mais les deux peuvent être fermés. */
function bibActivateRaceDetailBlock(block) {
if (!block) {
return;
}
let column = block.closest('.epr-col-right');
if (!column) {
return;
}
let btnToggle = block.querySelector('.epr-block-toggle');
if (!block.classList.contains('is-collapsed')) {
if (btnToggle) {
bibToggleCollapsibleBlock(block, btnToggle);
}
return;
}
column.querySelectorAll('.epr-block-gestion, .epr-block-assign').forEach(function (otherBlock) {
if (otherBlock === block || otherBlock.classList.contains('is-collapsed')) {
return;
}
let otherToggle = otherBlock.querySelector('.epr-block-toggle');
if (otherToggle) {
bibToggleCollapsibleBlock(otherBlock, otherToggle);
}
});
if (btnToggle) {
bibToggleCollapsibleBlock(block, btnToggle);
}
}
function bibCollapseGlobalBatchSection(section) {
if (!section || section.classList.contains('is-collapsed')) {
return;
}
var btnToggle = section.querySelector('.epr-block-toggle');
if (btnToggle) {
bibToggleCollapsibleBlock(section, btnToggle);
} else {
section.classList.add('is-collapsed');
var hdr = section.querySelector('.bib-global-batch__section-header');
if (hdr) {
hdr.setAttribute('aria-expanded', 'false');
}
}
}
function bibToggleGlobalBatchSection(section, btnToggle) {
if (!section || !btnToggle) {
return;
}
var willExpand = section.classList.contains('is-collapsed');
var root = bibGetGlobalBatchBody();
if (willExpand && root) {
root.querySelectorAll('.bib-global-batch__section').forEach(function (other) {
if (other !== section) {
bibCollapseGlobalBatchSection(other);
}
});
}
bibToggleCollapsibleBlock(section, btnToggle);
if (!section.classList.contains('is-collapsed')) {
if (section.classList.contains('bib-global-batch--existing')) {
updateGlobalBatchAnalysis();
} else if (section.classList.contains('bib-global-batch--generated')) {
updateGlobalBatchGeneratedAnalysis();
}
}
}
moduleBib.addEventListener('click', function (e) {
if (e.target.closest('.btn-aide-bib, .bib-aide-trigger, .btn-aide-trad, .btn-doc-trigger, .btn-admin-doc, .btn-trad-admin, .ms1-trad-link')) {
return;
}
let raceSummary = e.target.closest('.bib-race-summary');
if (raceSummary && moduleBib.contains(raceSummary)) {
if (e.target.closest('a, input, select, textarea, button:not(.bib-race-toggle)')) {
return;
}
e.preventDefault();
bibToggleRaceRow(raceSummary.closest('.epr-row'));
return;
}
let raceBlockHeader = e.target.closest(
'.epr-block-gestion > .epr-header--collapsible, .epr-block-assign > .epr-header--collapsible'
);
if (raceBlockHeader && moduleBib.contains(raceBlockHeader)) {
e.preventDefault();
bibActivateRaceDetailBlock(raceBlockHeader.closest('.epr-block'));
return;
}
let anomalyHdr = e.target.closest('.bib-anomaly-block-header');
if (anomalyHdr && moduleBib.contains(anomalyHdr) && !e.target.closest('.epr-block-toggle')) {
e.preventDefault();
let anomalyBlock = anomalyHdr.closest('.bib-anomaly-block');
let anomalyBtn = anomalyHdr.querySelector('.epr-block-toggle');
if (anomalyBlock && anomalyBtn) {
bibToggleCollapsibleBlock(anomalyBlock, anomalyBtn);
}
return;
}
let globalBatchHdr = e.target.closest('.bib-global-batch__section-header');
if (globalBatchHdr && moduleBib.contains(globalBatchHdr)
&& !e.target.closest('.epr-block-toggle, .btn-aide-bib, .bib-aide-trigger, .btn-aide-trad, .btn-trad-admin')) {
e.preventDefault();
let globalBatchSection = globalBatchHdr.closest('.bib-global-batch__section');
let globalBatchBtn = globalBatchHdr.querySelector('.epr-block-toggle');
if (globalBatchSection && globalBatchBtn) {
bibToggleGlobalBatchSection(globalBatchSection, globalBatchBtn);
}
return;
}
let btnToggle = e.target.closest('.epr-block-toggle');
if (!btnToggle || !moduleBib.contains(btnToggle)) {
return;
}
let globalBatchSection = btnToggle.closest('.bib-global-batch__section');
if (globalBatchSection && moduleBib.contains(globalBatchSection)) {
e.preventDefault();
bibToggleGlobalBatchSection(globalBatchSection, btnToggle);
return;
}
let anomalyBlock = btnToggle.closest('.bib-anomaly-block');
if (anomalyBlock) {
e.preventDefault();
bibToggleCollapsibleBlock(anomalyBlock, btnToggle);
return;
}
let block = btnToggle.closest('.epr-block');
if (!block || block.closest('#bib-tool-store')) {
return;
}
bibToggleCollapsibleBlock(block, btnToggle);
// MSIN-4424 — Sommaire quantités : chargement à la première ouverture (accordéon épreuve).
if (!block.classList.contains('is-collapsed') && block.id === 'bib-qty-summary-panel'
&& block.getAttribute('data-bib-qty-summary-deferred') === '1') {
refreshBibQtySummaryPanel();
}
// MSIN-4433 — Impression PDF : chargement à la première ouverture (accordéon épreuve).
if (!block.classList.contains('is-collapsed') && block.id === 'bib-dist-print-panel'
&& block.getAttribute('data-bib-dist-print-deferred') === '1') {
refreshBibDistPrintPanel();
}
});
moduleBib.addEventListener('keydown', function (e) {
if (e.key !== 'Enter' && e.key !== ' ') {
return;
}
let raceSummary = e.target.closest('.bib-race-summary');
if (raceSummary && moduleBib.contains(raceSummary)) {
if (e.target !== raceSummary && !e.target.closest('.bib-race-toggle')) {
return;
}
e.preventDefault();
bibToggleRaceRow(raceSummary.closest('.epr-row'));
return;
}
let globalBatchHdr = e.target.closest('.bib-global-batch__section-header');
if (globalBatchHdr && moduleBib.contains(globalBatchHdr)) {
e.preventDefault();
let globalBatchSection = globalBatchHdr.closest('.bib-global-batch__section');
let globalBatchBtn = globalBatchHdr.querySelector('.epr-block-toggle');
if (globalBatchSection && globalBatchBtn) {
bibToggleGlobalBatchSection(globalBatchSection, globalBatchBtn);
}
return;
}
let anomalyHdr = e.target.closest('.bib-anomaly-block-header');
if (!anomalyHdr || !moduleBib.contains(anomalyHdr)) {
return;
}
e.preventDefault();
let anomalyBlock = anomalyHdr.closest('.bib-anomaly-block');
let anomalyBtn = anomalyHdr.querySelector('.epr-block-toggle');
if (anomalyBlock && anomalyBtn) {
bibToggleCollapsibleBlock(anomalyBlock, anomalyBtn);
}
});
// ============================================================
// MSIN-4379 — Tippy.js (module #module-bib uniquement)
// info_texte → data-tippy-content (tip court)
// info_aide → data-tippy-content sur .btn-aide-bib (pop-up long)
// Ré-init après chaque refresh AJAX des séquences.
// ============================================================
function getBibContainer(row) {
if (!row) return null;
return row.querySelector('.epr-block-assign .epr-table.bib-container')
|| row.querySelector('.epr-table.bib-container')
|| row.querySelector('.epr-block-assign .bib-container')
|| row.querySelector('.bib-container');
}
function bibTippyEscapeHtml(str) {
return String(str)
.replace(/&/g, '&')
.replace(//g, '>')
.replace(/"/g, '"');
}
function bibTippyAideContent(reference) {
let span = reference.querySelector('.bib-aide-text');
if (!span) {
return '';
}
// Mini-formatage : retours à la ligne →
; double saut → paragraphe.
let lines = span.textContent.replace(/\r\n/g, '\n').replace(/\r/g, '\n').trim().split('\n');
let html = '';
let para = [];
lines.forEach(function (line) {
if (line.trim() === '') {
if (para.length) {
html += '' + para.join('
') + '
';
para = [];
}
} else {
para.push(bibTippyEscapeHtml(line));
}
});
if (para.length) {
html += '' + para.join('
') + '
';
}
return html;
}
function initModuleBibTippy(root) {
if (typeof tippy === 'undefined') return;
let scope = root || moduleBib;
scope.querySelectorAll('[data-tippy-content], .bib-aide-trigger').forEach(function (el) {
if (el._tippy) {
el._tippy.destroy();
}
});
tippy(scope.querySelectorAll('[data-tippy-content]'), {
theme: 'ms1-bib',
animation: 'fade',
allowHTML: false,
maxWidth: 280,
interactive: false,
appendTo: function () { return document.body; },
zIndex: 10050
});
tippy(scope.querySelectorAll('.bib-aide-trigger'), {
theme: 'ms1-bib ms1-bib-aide',
animation: 'fade',
allowHTML: true,
maxWidth: 420,
interactive: true,
content: bibTippyAideContent,
appendTo: function () { return document.body; },
zIndex: 10050
});
}
/** Visibilité UI v4 — bib-ui-hidden sur le conteneur (bouton + ? ensemble). */
function bibQuery(row, selector) {
return (row || moduleBib).querySelector(selector);
}
function bibSetVisible(target, show, row) {
let el = target;
if (typeof target === 'string') {
el = bibQuery(row, target);
} else if (el && el.nodeType === 1
&& !el.classList.contains('epr-action-group')
&& !el.classList.contains('batch-config-container')
&& !el.classList.contains('auto-config-container')
&& !el.classList.contains('epr-add-range-row')) {
el = el.closest('.epr-action-group') || el;
}
if (el) {
el.classList.toggle('bib-ui-hidden', !show);
if (el.classList.contains('epr-action-reset-group')) {
let advanced = el.closest('.bib-advanced-actions');
if (advanced) {
advanced.classList.toggle('bib-ui-hidden', !show);
}
}
if (el.classList.contains('epr-action-batch-group')
|| el.classList.contains('epr-action-auto-group')) {
let method = el.closest('.bib-assignment-method');
if (method) {
method.classList.toggle('bib-ui-hidden', !show);
}
}
}
}
function bibRowModes(row) {
return {
batch: row.classList.contains('batch-mode'),
auto: row.classList.contains('auto-mode'),
reset: row.classList.contains('reset-mode'),
};
}
function bibHasSavedSequences(row) {
return Array.from(row.querySelectorAll('.bib-range[data-id]')).some(function (line) {
return parseInt(line.getAttribute('data-id') || '0', 10) > 0;
});
}
function bibCountSelectedRanges(row) {
return row.querySelectorAll('.batch-select-range:checked').length;
}
/** MSIN-4436 — Développe un bloc repliable #module-bib. */
function bibExpandBlock(block) {
if (!block || !block.classList.contains('is-collapsed')) {
return;
}
block.classList.remove('is-collapsed');
let btn = block.querySelector('.epr-block-toggle');
if (btn) {
btn.setAttribute('aria-expanded', 'true');
let label = btn.getAttribute('data-label-collapse') || '';
if (label) {
btn.setAttribute('aria-label', label);
btn.setAttribute('title', label);
}
let icon = btn.querySelector('.fa');
if (icon) {
icon.classList.add('fa-chevron-up');
icon.classList.remove('fa-chevron-down');
}
}
}
let bibFocusApplied = false;
/** MSIN-4436 — Retour depuis fiche inscription : rouvrir le panneau ciblé. */
function bibApplyFocusFromUrlOnce() {
if (bibFocusApplied) {
return;
}
let focus = new URLSearchParams(window.location.search).get('bib_focus');
if (!focus) {
return;
}
bibFocusApplied = true;
let focusMap = {
anomalies: 'anomalies',
qty_summary: 'qty_summary',
dist_print: 'dist_print',
event_config: 'event_config'
};
let toolId = focusMap[focus];
if (!toolId) {
return;
}
bibSetWorkspace(bibWorkspaceForTool(toolId), { keepTool: true });
bibOpenTool(toolId).then(function () {
let detail = document.getElementById('bib-tool-detail');
if (detail) {
detail.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
});
}
/** MSIN-4379 — Rafraîchit le dashboard anomalies (chien de garde). */
function refreshBibAnomaliesPanel() {
let mount = document.getElementById('bib-anomalies-mount');
if (!mount || !moduleBib) {
return Promise.resolve();
}
let eveId = moduleBib.dataset.eveId || '';
if (!eveId) {
return Promise.resolve();
}
return bibFetch('/ajax_bib_range.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: 'action=anomalies&eve_id=' + encodeURIComponent(eveId) + bibAjaxLangSuffix()
}, { loader: false })
.then(function (res) { return res.json(); })
.then(function (data) {
if (!data.success || !data.html) {
return;
}
let blnWasActive = bibActiveTool === 'anomalies';
if (blnWasActive) {
bibRestoreToolContent('anomalies');
}
bibInvalidateToolSlot('anomalies');
mount.innerHTML = data.html;
initModuleBibTippy(mount);
bibSyncToolNavBadges('anomalies');
bibRemountActiveToolAfterRefresh('anomalies');
});
}
/** MSIN-4433 — Rafraîchit le panneau impression PDF. */
function refreshBibDistPrintPanel() {
let mount = document.getElementById('bib-dist-print-mount');
if (!mount || !moduleBib) {
return Promise.resolve();
}
let panel = document.getElementById('bib-dist-print-panel');
let blnDeferred = panel && panel.getAttribute('data-bib-dist-print-deferred') === '1';
let blnLoaded = panel && panel.getAttribute('data-bib-dist-print-loaded') === '1';
if (!blnDeferred && !blnLoaded) {
return Promise.resolve();
}
let eveId = moduleBib.dataset.eveId || '';
if (!eveId) {
return Promise.resolve();
}
let blnWasActive = bibActiveTool === 'dist_print';
return bibFetch('/ajax_bib_range.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: 'action=dist_print_panel&eve_id=' + encodeURIComponent(eveId) + bibAjaxLangSuffix()
}, { loader: false })
.then(function (res) { return res.json(); })
.then(function (data) {
if (!data.success || !data.html) {
return;
}
if (blnWasActive) {
bibRestoreToolContent('dist_print');
}
bibInvalidateToolSlot('dist_print');
mount.innerHTML = data.html;
initModuleBibTippy(mount);
initBibDistPrintPanel(mount);
bibRemountActiveToolAfterRefresh('dist_print');
});
}
/** MSIN-4433 — Limite questions + rafraîchissement après génération PDF. */
function initBibDistPrintPanel(root) {
root = root || document;
let panel = root.querySelector ? root.querySelector('#bib-dist-print-panel') : null;
if (!panel) {
panel = document.getElementById('bib-dist-print-panel');
}
if (!panel || panel.getAttribute('data-bib-dist-print-init') === '1') {
return;
}
panel.setAttribute('data-bib-dist-print-init', '1');
let intMax = parseInt(panel.getAttribute('data-max-questions') || '5', 10);
if (!intMax || intMax < 1) {
intMax = 5;
}
panel.addEventListener('change', function (ev) {
let cb = ev.target;
if (!cb || !cb.classList || !cb.classList.contains('bib-dist-print-question-cb')) {
return;
}
if (!cb.checked) {
return;
}
let section = cb.closest('.bib-dist-print-epr');
if (!section) {
return;
}
let tabChecked = section.querySelectorAll('.bib-dist-print-question-cb:checked');
if (tabChecked.length > intMax) {
cb.checked = false;
}
});
let form = panel.querySelector('.bib-dist-print-form');
if (form) {
form.addEventListener('submit', function () {
window.setTimeout(function () {
refreshBibDistPrintPanel();
}, 1500);
});
}
}
/** MSIN-4424 — Rafraîchit le sommaire des quantités (si déjà chargé ou ouverture). */
function refreshBibQtySummaryPanel() {
let mount = document.getElementById('bib-qty-summary-mount');
if (!mount || !moduleBib) {
return Promise.resolve();
}
let panel = document.getElementById('bib-qty-summary-panel');
let blnDeferred = panel && panel.getAttribute('data-bib-qty-summary-deferred') === '1';
let blnLoaded = panel && panel.getAttribute('data-bib-qty-summary-loaded') === '1';
if (!blnDeferred && !blnLoaded) {
return Promise.resolve();
}
let eveId = moduleBib.dataset.eveId || '';
if (!eveId) {
return Promise.resolve();
}
let blnWasActive = bibActiveTool === 'qty_summary';
return bibFetch('/ajax_bib_range.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: 'action=qty_summary&eve_id=' + encodeURIComponent(eveId) + bibAjaxLangSuffix()
}, { loader: false })
.then(function (res) { return res.json(); })
.then(function (data) {
if (!data.success || !data.html) {
return;
}
if (blnWasActive) {
bibRestoreToolContent('qty_summary');
}
bibInvalidateToolSlot('qty_summary');
mount.innerHTML = data.html;
initModuleBibTippy(mount);
bibSyncToolNavBadges('qty_summary');
bibRemountActiveToolAfterRefresh('qty_summary');
});
}
function bibQtySummaryShouldRefresh() {
let panel = document.getElementById('bib-qty-summary-panel');
return panel && panel.getAttribute('data-bib-qty-summary-loaded') === '1';
}
function setBibContainerHtml(row, html, opts) {
opts = opts || {};
let container = getBibContainer(row);
if (!container) return null;
// renderBibRanges renvoie un bloc .epr-table.bib-container complet.
if (html.indexOf('bib-container') !== -1) {
container.outerHTML = html;
container = getBibContainer(row);
} else {
container.innerHTML = html;
}
// MSIN-4446 — Pastille « N séquence(s) » hors du conteneur AJAX.
if (opts.summaryHtml != null) {
let summaries = row.querySelector('.epr-block-assign .epr-header-summaries');
if (summaries) {
summaries.innerHTML = opts.summaryHtml;
}
}
if (typeof opts.seqCount !== 'undefined') {
let summaryRanges = row.querySelector('.bib-race-summary-ranges');
if (summaryRanges) {
summaryRanges.textContent = parseInt(opts.seqCount, 10) || 0;
}
let productionRanges = moduleBib.querySelector(
'.bib-production-category[data-epr-id="' + row.dataset.eprId + '"] .bib-production-range-count'
);
if (productionRanges) {
productionRanges.textContent = parseInt(opts.seqCount, 10) || 0;
}
bibSyncRaceSummaryStatus(row);
}
if (typeof opts.autoActive !== 'undefined') {
let blnAuto = !!opts.autoActive && opts.autoActive !== '0' && opts.autoActive !== 0;
row.dataset.autoActive = blnAuto ? '1' : '0';
row.classList.toggle('auto-enabled', blnAuto);
}
if (container) {
initModuleBibTippy(row);
initBibRangeRows(container);
}
syncBibUiState(row);
if (!opts.skipAnomalies) {
refreshBibAnomaliesPanel();
}
if (!opts.skipQtySummary && bibQtySummaryShouldRefresh()) {
refreshBibQtySummaryPanel();
}
return container;
}
/** MSIN-4446 — Applique html + pastille résumé depuis une réponse AJAX ranges. */
function setBibContainerFromAjax(row, data, opts) {
opts = opts || {};
if (data && data.summary_html != null) {
opts.summaryHtml = data.summary_html;
}
if (data && typeof data.seq_count !== 'undefined') {
opts.seqCount = data.seq_count;
}
if (data && typeof data.auto_active !== 'undefined') {
opts.autoActive = data.auto_active;
}
return setBibContainerHtml(row, data.html, opts);
}
// MSIN-4429 — Séquence : Début puis Qté ou Fin (pilote / calculé).
function bibRangeParseInt(val) {
var n = parseInt(String(val || '').trim(), 10);
return isNaN(n) ? 0 : n;
}
function bibRangeGetFields(row) {
if (!row) return null;
return {
start: row.querySelector('.bib-start'),
qty: row.querySelector('.bib-qty'),
end: row.querySelector('.bib-end')
};
}
function bibRangeGetErrorEl(row) {
var el = row && row.nextElementSibling;
if (el && el.classList.contains('bib-error')) {
return el;
}
return null;
}
function bibRangeClearRangeError(row) {
var errEl = bibRangeGetErrorEl(row);
if (!errEl) return;
var msg = errEl.querySelector('.bib-range-validate-msg');
if (msg) {
msg.remove();
}
if (!errEl.querySelector('div:not(.bib-range-validate-msg)') && !errEl.textContent.trim()) {
errEl.style.display = 'none';
}
}
function bibRangeClearFieldClasses(row) {
var fields = bibRangeGetFields(row);
if (!fields) return;
[fields.start, fields.qty, fields.end].forEach(function (el) {
if (!el) return;
el.classList.remove('bib-field--idle', 'bib-field--pick', 'bib-field--calc', 'bib-field--active');
});
}
function bibRangeClearValidationUi(row) {
var fields = bibRangeGetFields(row);
if (!fields) return;
[fields.start, fields.qty, fields.end].forEach(function (el) {
if (el) {
el.classList.remove('bib-field--invalid');
}
});
bibRangeClearRangeError(row);
}
/** MSIN-4429 — Validation différée (blur / OK), pas pendant la frappe. */
function bibRangeValidate(row) {
var fields = bibRangeGetFields(row);
if (!fields) return null;
var start = bibRangeParseInt(fields.start && fields.start.value);
if (start <= 0) {
return null;
}
var pilot = row.dataset.rangePilot || '';
if (!pilot) {
return null;
}
if (pilot === 'end') {
var strEnd = String(fields.end && fields.end.value || '').trim();
if (strEnd === '') {
return null;
}
var end = bibRangeParseInt(strEnd);
if (end <= 0) {
return { key: 'incomplete', field: 'end' };
}
if (end < start) {
return { key: 'invalidEnd', field: 'end', start: start };
}
}
if (pilot === 'qty') {
var strQty = String(fields.qty && fields.qty.value || '').trim();
if (strQty === '') {
return null;
}
var qty = bibRangeParseInt(strQty);
if (qty <= 0) {
return { key: 'invalidQty', field: 'qty' };
}
}
return null;
}
function bibRangeValidationMessage(validation) {
if (!validation) {
return '';
}
if (validation.key === 'invalidEnd') {
return bibJsFmt('jsRangeInvalidEnd', validation.start);
}
if (validation.key === 'invalidQty') {
return bibJs('jsRangeInvalidQty');
}
if (validation.key === 'incomplete') {
return bibJs('jsRangeIncomplete') || bibJs('jsFieldsRequired');
}
return bibJs('jsRangeInvalid') || bibJs('jsFieldsRequired');
}
function bibRangeShowValidation(row, validation) {
var fields = bibRangeGetFields(row);
if (!fields) {
return;
}
bibRangeClearValidationUi(row);
if (!validation) {
return;
}
var target = validation.field === 'qty' ? fields.qty : fields.end;
if (target) {
target.classList.add('bib-field--invalid');
}
var errEl = bibRangeGetErrorEl(row);
if (!errEl) {
return;
}
var msgEl = errEl.querySelector('.bib-range-validate-msg');
if (!msgEl) {
msgEl = document.createElement('div');
msgEl.className = 'bib-range-validate-msg';
errEl.insertBefore(msgEl, errEl.firstChild);
}
msgEl.textContent = bibRangeValidationMessage(validation);
errEl.style.display = 'block';
}
function bibRangeValidateOnBlur(row) {
applyBibRangeFieldState(row);
bibRangeShowValidation(row, bibRangeValidate(row));
}
function applyBibRangeFieldState(row) {
var fields = bibRangeGetFields(row);
if (!fields || !fields.start || !fields.qty || !fields.end) return;
if (row.dataset.locked === '1') {
bibRangeClearFieldClasses(row);
return;
}
var start = bibRangeParseInt(fields.start.value);
var pilot = row.dataset.rangePilot || '';
bibRangeClearFieldClasses(row);
if (start <= 0) {
fields.qty.classList.add('bib-field--idle');
fields.end.classList.add('bib-field--idle');
fields.qty.readOnly = true;
fields.end.readOnly = true;
fields.qty.value = '';
fields.end.value = '';
row.dataset.rangePilot = '';
return;
}
if (!pilot) {
fields.qty.classList.add('bib-field--pick');
fields.end.classList.add('bib-field--pick');
fields.qty.readOnly = true;
fields.end.readOnly = true;
return;
}
if (pilot === 'qty') {
var qty = bibRangeParseInt(fields.qty.value);
fields.qty.classList.add('bib-field--active');
fields.end.classList.add('bib-field--calc');
fields.qty.readOnly = false;
fields.end.readOnly = true;
if (qty > 0) {
fields.end.value = String(start + qty - 1);
} else {
fields.end.value = '';
}
} else if (pilot === 'end') {
var end = bibRangeParseInt(fields.end.value);
fields.end.classList.add('bib-field--active');
fields.qty.classList.add('bib-field--calc');
fields.end.readOnly = false;
fields.qty.readOnly = true;
if (end >= start) {
fields.qty.value = String(end - start + 1);
} else {
fields.qty.value = '';
}
}
}
function onBibRangeFieldPick(row, pilot) {
if (!row || row.dataset.locked === '1') return;
var fields = bibRangeGetFields(row);
if (!fields || !fields.start) return;
if (bibRangeParseInt(fields.start.value) <= 0) {
fields.start.focus();
return;
}
row.dataset.rangePilot = pilot;
applyBibRangeFieldState(row);
var target = pilot === 'qty' ? fields.qty : fields.end;
if (target) {
target.focus();
target.select();
}
}
function onBibRangeStartChange(row) {
var fields = bibRangeGetFields(row);
if (!fields || !fields.start) return;
var start = bibRangeParseInt(fields.start.value);
var lastStart = bibRangeParseInt(row.dataset.rangeLastStart || '0');
if (start !== lastStart && !row.dataset.rangePilot) {
fields.qty.value = '';
fields.end.value = '';
row.dataset.hasValues = '0';
}
row.dataset.rangeLastStart = String(start);
if (start <= 0) {
row.dataset.rangePilot = '';
}
applyBibRangeFieldState(row);
}
function bindBibRangeRow(row) {
if (!row || row.dataset.bibRangeBound === '1') return;
row.dataset.bibRangeBound = '1';
var fields = bibRangeGetFields(row);
if (!fields || !fields.start || !fields.qty || !fields.end) return;
row.dataset.rangeLastStart = String(bibRangeParseInt(fields.start.value));
fields.start.addEventListener('input', function () {
bibRangeClearValidationUi(row);
onBibRangeStartChange(row);
});
fields.qty.addEventListener('input', function () {
bibRangeClearValidationUi(row);
row.dataset.rangePilot = 'qty';
applyBibRangeFieldState(row);
});
fields.end.addEventListener('input', function () {
bibRangeClearValidationUi(row);
row.dataset.rangePilot = 'end';
applyBibRangeFieldState(row);
});
fields.start.addEventListener('blur', function () {
bibRangeValidateOnBlur(row);
});
fields.qty.addEventListener('blur', function () {
bibRangeValidateOnBlur(row);
});
fields.end.addEventListener('blur', function () {
bibRangeValidateOnBlur(row);
});
fields.qty.addEventListener('click', function () {
onBibRangeFieldPick(row, 'qty');
});
fields.end.addEventListener('click', function () {
onBibRangeFieldPick(row, 'end');
});
fields.qty.addEventListener('focus', function () {
onBibRangeFieldPick(row, 'qty');
});
fields.end.addEventListener('focus', function () {
onBibRangeFieldPick(row, 'end');
});
applyBibRangeFieldState(row);
if (row.dataset.id === '0' && !fields.start.value) {
fields.start.focus();
}
}
function initBibRangeRows(root) {
if (!root) return;
root.querySelectorAll('.bib-range').forEach(bindBibRangeRow);
}
function bibCsrfToken() {
return moduleBib ? (moduleBib.dataset.csrfToken || '') : '';
}
initModuleBibTippy(moduleBib);
initBibRangeRows(moduleBib);
// ============================================================
// MSIN-4379 — Étape 2 : assignation automatique (interface JS)
// Prochain tour : étape 6 (fxAssignAutoBibForParticipant), étape 7 (fxMajCommande).
// ============================================================
/** MSIN-4379 — Compte les séquences cochées et met à jour le texte d'aide. */
function updateAutoSelectionInfo(row) {
if (!row) return;
let count = row.querySelectorAll('.batch-select-range:checked').length;
let info = row.querySelector('.auto-info-text');
if (!info) return;
if (count === 0) {
info.textContent = bibJs('jsAutoSelectHint');
} else {
info.textContent = bibJsFmt('jsAutoSelectCount', count);
}
}
function syncAutoUiState(row, isActive) {
if (!row) return;
let btnAuto = row.querySelector('.btn-auto');
row.dataset.autoActive = isActive ? '1' : '0';
row.classList.toggle('auto-enabled', isActive);
if (btnAuto) {
btnAuto.textContent = isActive ? row.dataset.autoLabelConfig : row.dataset.autoLabel;
btnAuto.classList.toggle('btn-bib-auto--active', isActive);
let autoAide = bibQuery(row, '.epr-action-auto-group .epr-btn-aide-segment .bib-aide-trigger');
if (autoAide) {
autoAide.classList.add('btn-aide-tone-auto');
autoAide.classList.remove('btn-aide-tone-success', 'btn-aide-tone-secondary');
}
}
}
/** MSIN-4379 — Quitte le mode édition auto sans sauver ; recharge les plages (mode assign). */
function exitAutoMode(row) {
if (!row) return;
row.classList.remove('auto-mode');
let container = row.querySelector('.bib-container');
if (container) {
container.classList.remove('batch-mode');
}
row.querySelectorAll('.bib-start, .bib-qty, .bib-end').forEach(input => {
input.removeAttribute('readonly');
});
bibFetch('/ajax_bib_range.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body:
'action=refresh_ranges'
+ '&epr_id=' + encodeURIComponent(row.dataset.eprId)
+ '&mode=assign'
+ bibAjaxLangSuffix()
})
.then(res => res.json())
.then(data => {
if (!data.success) return;
let bibContainer = setBibContainerFromAjax(row, data);
});
}
/** MSIN-4379 — Ouvre le mode édition : checkboxes, bloc Accepter/Annuler, refresh mode=auto. */
function enterAutoMode(row) {
if (!row) return;
if (row.classList.contains('batch-mode') || row.classList.contains('reset-mode')) {
return;
}
if (bibBlockAutoActivation(row)) {
return;
}
row.classList.add('auto-mode');
let container = row.querySelector('.bib-container');
if (container) {
container.classList.add('batch-mode');
}
row.querySelectorAll('.bib-start, .bib-qty, .bib-end').forEach(input => {
input.setAttribute('readonly', true);
});
syncBibUiState(row);
bibFetch('/ajax_bib_range.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body:
'action=refresh_ranges'
+ '&epr_id=' + encodeURIComponent(row.dataset.eprId)
+ '&mode=auto'
+ bibAjaxLangSuffix()
})
.then(res => res.json())
.then(data => {
if (!data.success) return;
let bibContainer = setBibContainerFromAjax(row, data);
if (!bibContainer) return;
bibContainer.classList.add('batch-mode');
row.querySelectorAll('.bib-start, .bib-qty, .bib-end').forEach(input => {
input.setAttribute('readonly', true);
});
updateAutoSelectionInfo(row);
syncBibUiState(row);
});
}
function bibSyncResetAllEprButton(row) {
if (!row) {
return;
}
let wrap = row.querySelector('.epr-identity-reset-all');
if (!wrap) {
return;
}
let avecBib = parseInt(bibQuery(row, '.bib-avec')?.textContent || '0', 10) || 0;
if (avecBib <= 0) {
wrap.classList.add('bib-ui-hidden');
return;
}
wrap.classList.remove('bib-ui-hidden');
let btn = wrap.querySelector('.btn-reset-all-epr');
if (!btn) {
return;
}
let hasLock = row.querySelector('.btn-bib-lock--closed') !== null;
btn.disabled = hasLock;
}
function syncBibUiState(row) {
if (!row) return;
let modes = bibRowModes(row);
let avecBib = parseInt(bibQuery(row, '.bib-avec')?.textContent || '0', 10) || 0;
let hasSequences = bibHasSavedSequences(row);
let hasSelection = bibCountSelectedRanges(row) > 0;
let inBatchFlow = modes.batch || modes.reset;
let inAutoFlow = modes.auto;
let inPickFlow = inBatchFlow || inAutoFlow;
row.querySelectorAll('.team-mode-box input[type="radio"]').forEach(function (radio) {
if (!radio.closest('.team-mode-option.disabled')) {
radio.disabled = avecBib > 0;
}
});
let showReset = hasSequences && (avecBib > 0 || modes.reset)
&& !modes.auto
&& (!modes.batch || modes.reset);
bibSetVisible('.epr-action-batch-group',
hasSequences && ((!modes.reset && !modes.auto) || modes.batch), row);
bibSetVisible('.epr-action-reset-group', showReset, row);
bibSetVisible('.epr-action-auto-group',
hasSequences && !modes.reset && !modes.auto && !modes.batch, row);
if (hasSequences) {
syncAutoUiState(row, row.dataset.autoActive === '1');
}
bibSetVisible('.epr-add-range-row', !inPickFlow, row);
bibSetVisible('.batch-config-container', inBatchFlow, row);
bibSetVisible('.auto-config-container', inAutoFlow, row);
let showPick = inPickFlow && !hasSelection;
let showBatchReady = inBatchFlow && hasSelection;
let showAutoReady = inAutoFlow && hasSelection;
bibSetVisible('.bib-seq-pick-prompt', showPick, row);
bibSetVisible('.batch-config-ready', showBatchReady, row);
bibSetVisible('.auto-config-ready', showAutoReady, row);
let bibContainer = getBibContainer(row);
if (bibContainer) {
bibContainer.classList.toggle('batch-awaiting-selection', showPick);
}
bibSetVisible('.epr-action-desactiver-group',
hasSequences && row.dataset.autoActive === '1' && inAutoFlow, row);
bibSetVisible('.epr-action-cancel-auto-group', inAutoFlow, row);
bibSetVisible('.epr-action-accept-auto-group', showAutoReady, row);
bibSetVisible('.epr-auto-info-group', showAutoReady, row);
bibSetVisible('.batch-reset-warning', showBatchReady && modes.reset, row);
bibSetVisible('.epr-batch-order-wrap', showBatchReady && !modes.reset, row);
bibSetVisible('.epr-batch-order-wrap--secondary', showBatchReady && !modes.reset, row);
bibSetVisible('.epr-action-sim-group', showBatchReady && !modes.reset, row);
bibSetVisible('.epr-action-go-group', showBatchReady, row);
bibSyncResetAllEprButton(row);
}
function updateBatchAnalysis(row) {
if (!row) return;
let totalDispo = 0;
let totalReset = 0;
// =====================
// TOTAL DISPO
// Source officielle = PHP
// JS ne recalcule PAS les disponibilités.
// Il additionne seulement les valeurs affichées dans .bib-dispo.
// =====================
row.querySelectorAll('.batch-select-range:checked').forEach(cb => {
let line = cb.closest('.epr-line');
if (!line) return;
let usedDiv = line.querySelector('.bib-used');
let dispoDiv = line.querySelector('.bib-dispo');
let used = parseInt((usedDiv?.textContent || '0'), 10);
let dispo = parseInt((dispoDiv?.textContent || '0'), 10);
if (isNaN(used)) {
used = 0;
}
if (isNaN(dispo)) {
dispo = 0;
}
totalReset += used;
totalDispo += dispo;
});
bibFetch('/ajax_bib_range.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: 'action=batch_analysis&epr_id=' + encodeURIComponent(row.dataset.eprId) + bibAjaxLangSuffix()
}, { loader: false })
.then(res => res.json())
.then(data => {
if (!data.success) return;
bibSyncEprBibStats(row, data.info);
syncBibUiState(row);
let sansBib = bibRowPendingBibs(row);
let isResetMode = row.dataset.mode === 'reset';
let message = '';
if (isResetMode) {
if (totalReset === 0) {
message = bibJs('jsBatchNone');
} else {
message = bibJsFmt('jsBatchResetCount', totalReset);
}
} else {
if (totalDispo === 0) {
message = bibJs('jsBatchNone');
} else if (totalDispo < sansBib) {
message = bibJsFmt('jsBatchSummaryShort', totalDispo, sansBib, sansBib - totalDispo);
} else {
message = bibJsFmt('jsBatchSummaryOk', totalDispo, sansBib);
}
}
let info = row.querySelector('.epr-actions .batch-info-text');
if (info && bibCountSelectedRanges(row) > 0) {
info.textContent = message;
}
syncBibUiState(row);
});
}
// =====================
// BATCH CHECKBOX CHANGE (PROPRE)
// =====================
moduleBib.addEventListener('change', function (e) {
// =====================
// TEAM MODE
// =====================
let teamRadio = e.target.closest('.team-mode-box input[type="radio"]');
if (teamRadio) {
if (teamRadio.disabled) return;
let box = teamRadio.closest('.team-mode-box');
if (!box) return;
bibFetch('/ajax_bib_range.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body:
'action=save_team_mode'
+ '&epr_id=' + encodeURIComponent(box.dataset.eprId)
+ '&team_mode=' + encodeURIComponent(teamRadio.value)
+ bibAjaxLangSuffix()
}, { loader: false })
.then(function (res) { return res.json(); })
.then(function (data) {
if (!data.success) {
alert(data.message || bibJs('jsErrGeneric'));
return;
}
let row = teamRadio.closest('.epr-row');
let summary = row ? row.querySelector('.bib-race-summary-team-mode') : null;
let optionLabel = teamRadio.closest('.team-mode-option');
let optionText = optionLabel ? optionLabel.querySelector('span') : null;
if (summary && optionText) {
summary.textContent = optionText.textContent.trim();
}
});
return;
}
let cb = e.target.closest('.batch-select-range');
if (!cb) return;
let row = cb.closest('.epr-row');
if (!row) return;
// MSIN-4379 — Mode auto : même sélection de séquences que le batch, sans GO/simulation.
if (row.classList.contains('auto-mode')) {
updateAutoSelectionInfo(row);
syncBibUiState(row);
return;
}
if (row.dataset.loading === '1') return;
let existing = document.querySelector('.epr-row-view');
if (existing) existing.remove();
row.dataset.loading = '1';
// 1. garder sélection
let selected = [];
row.querySelectorAll('.batch-select-range:checked').forEach(el => {
selected.push(el.dataset.rangeId);
});
// 2. analyse gauche/droite
updateBatchAnalysis(row);
// 3. sortir du cycle du change
setTimeout(() => {
bibFetch('/ajax_bib_range.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body:
'action=refresh_ranges'
+ '&epr_id=' + encodeURIComponent(row.dataset.eprId)
+ '&mode=' + encodeURIComponent(row.dataset.mode || 'assign')
+ bibAjaxLangSuffix()
}, { loader: false })
.then(res => res.json())
.then(data => {
if (!data.success) {
row.dataset.loading = '0';
return;
}
setBibContainerFromAjax(row, data);
let container = getBibContainer(row);
if (!container) {
row.dataset.loading = '0';
return;
}
// 4. refresh complet serveur
// Re-sync après refresh serveur
container.classList.add('batch-mode');
// 5. remettre readonly
container.querySelectorAll('.bib-start, .bib-qty, .bib-end').forEach(input => {
input.setAttribute('readonly', true);
});
// 6. restaurer checkbox
container.querySelectorAll('.batch-select-range').forEach(el => {
if (selected.includes(el.dataset.rangeId)) {
el.checked = true;
}
});
updateBatchAnalysis(row);
row.dataset.loading = '0';
})
.catch(() => {
row.dataset.loading = '0';
});
}, 0);
});
moduleBib.querySelectorAll('.epr-row').forEach(syncBibUiState);
moduleBib.addEventListener('click', function (e) {
let btnQte = e.target.closest('.btn_qte');
if (btnQte && moduleBib.contains(btnQte)) {
e.preventDefault();
bibSaveQte(btnQte);
return;
}
let btnGotoAssign = e.target.closest('.bib-anomaly-goto-assign');
if (btnGotoAssign) {
e.preventDefault();
let eprId = btnGotoAssign.dataset.eprId;
if (!eprId) {
return;
}
let row = moduleBib.querySelector('.epr-row[data-epr-id="' + eprId + '"]');
if (row) {
row.scrollIntoView({ behavior: 'smooth', block: 'start' });
let btnView = row.querySelector('.btn-view-range[data-range-id="0"]');
if (btnView) {
btnView.click();
}
}
return;
}
let btnTrad = e.target.closest('.btn-admin-trad, .btn-bib-trad');
if (btnTrad) {
e.preventDefault();
e.stopPropagation();
let url = btnTrad.getAttribute('data-trad-url');
if (!url) {
return;
}
let clef = btnTrad.getAttribute('data-info-clef') || 'bib_trad';
let popup = window.open(
url,
'bib_trad_' + clef,
'width=960,height=640,scrollbars=yes,resizable=yes'
);
if (popup) {
let timer = setInterval(function () {
if (popup.closed) {
clearInterval(timer);
window.location.reload();
}
}, 400);
}
return;
}
// =====================
// LOCK / UNLOCK SEQUENCE
// =====================
let btnLock = e.target.closest('.btn-bib-lock');
if (btnLock) {
e.preventDefault();
let row = btnLock.closest('.epr-row');
if (!row) return;
let isLocked = btnLock.dataset.locked === '1';
let confirmMsg = isLocked
? bibJsConfirm('jsUnlockConfirm')
: bibJsConfirm('jsLockConfirm');
if (!confirm(confirmMsg)) {
return;
}
bibFetch('/ajax_bib_range.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body:
'action=toggle_lock'
+ '&epr_bib_id=' + encodeURIComponent(btnLock.dataset.rangeId)
+ '&epr_id=' + encodeURIComponent(btnLock.dataset.eprId || row.dataset.eprId)
+ '&locked=' + encodeURIComponent(isLocked ? '0' : '1')
+ bibAjaxLangSuffix()
})
.then(res => res.json())
.then(data => {
if (!data.success) {
alert(data.message || bibJs('jsErrGeneric'));
return;
}
if (typeof data.auto_active !== 'undefined') {
row.dataset.autoActive = data.auto_active ? '1' : '0';
syncAutoUiState(row, data.auto_active);
syncBibUiState(row);
}
if (data.html) {
setBibContainerFromAjax(row, data);
bibSyncResetAllEprButton(row);
}
});
return;
}
// =====================
// MSIN-4436 — Réinitialiser tous les dossards (épreuve entière)
// =====================
let btnResetAllEpr = e.target.closest('.btn-reset-all-epr');
if (btnResetAllEpr) {
e.preventDefault();
let row = btnResetAllEpr.closest('.epr-row');
if (!row) {
return;
}
if (btnResetAllEpr.disabled) {
alert(bibJsConfirm('jsResetAllLocked'));
return;
}
if (row.querySelector('.btn-bib-lock--closed')) {
alert(bibJsConfirm('jsResetAllLocked'));
bibSyncResetAllEprButton(row);
return;
}
if (!confirm(bibJsConfirm('jsResetAllConfirm'))) {
return;
}
bibFetch('/ajax_bib_range.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body:
'action=reset_all_apply'
+ '&epr_id=' + encodeURIComponent(row.dataset.eprId)
+ bibAjaxLangSuffix()
})
.then(res => res.json())
.then(data => {
if (!data.success) {
alert(data.message || bibJs('jsErrGeneric'));
return;
}
bibAfterBatchGoSuccess(row, data, false);
});
return;
}
// =====================
// DELETE
// =====================
let btnDelete = e.target.closest('.btn-delete-range');
if (btnDelete) {
e.preventDefault();
let container = btnDelete.closest('.bib-container');
let errorDiv = container.querySelector('.bib-error-global');
// reset erreur
if (errorDiv) {
errorDiv.style.display = 'none';
errorDiv.innerText = '';
}
let id = btnDelete.dataset.id;
if (!id) return;
let rowDelete = btnDelete.closest('.epr-row');
let eprIdDelete = rowDelete ? rowDelete.dataset.eprId : '';
bibFetch('/ajax_bib_range.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: 'action=delete'
+ '&id=' + encodeURIComponent(id)
+ '&epr_id=' + encodeURIComponent(eprIdDelete)
+ bibAjaxLangSuffix()
})
.then(res => res.text())
.then(raw => {
let data;
try {
data = JSON.parse(raw);
} catch (err) {
if (errorDiv) {
errorDiv.innerText = bibJs('jsServerError');
errorDiv.style.display = 'block';
}
return;
}
if (!data.success) {
if (errorDiv) {
errorDiv.innerText = data.message || bibJs('jsErrGeneric');
errorDiv.style.display = 'block';
}
return;
}
// MSIN-4446 — Rafraîchir aussi la pastille « N séquence(s) ».
setBibContainerFromAjax(btnDelete.closest('.epr-row'), data);
});
return;
}
// =====================
// SAVE
// =====================
let btnSave = e.target.closest('.btn-save-range');
if (btnSave) {
e.preventDefault();
let row = btnSave.closest('.bib-range');
let errorDiv = row.nextElementSibling;
let epr_id = btnSave.dataset.eprId;
// reset
if (errorDiv) {
errorDiv.style.display = 'none';
errorDiv.innerText = '';
}
applyBibRangeFieldState(row);
let start = bibRangeParseInt(row.querySelector('.bib-start').value);
let end = bibRangeParseInt(row.querySelector('.bib-end').value);
let id = btnSave.dataset.id;
let validation = bibRangeValidate(row);
// ligne temporaire vide = on la retire
if (id == 0 && start <= 0) {
row.remove();
if (errorDiv && errorDiv.classList.contains('bib-error')) {
errorDiv.remove();
}
return;
}
if (start <= 0 || end <= 0) {
validation = validation || { key: 'incomplete' };
}
if (!validation && end < start) {
validation = { key: 'invalidEnd', field: 'end', start: start };
}
if (validation) {
bibRangeShowValidation(row, validation);
if (errorDiv) {
var msgEl = errorDiv.querySelector('.bib-range-validate-msg');
if (!msgEl) {
errorDiv.innerText = bibRangeValidationMessage(validation);
}
errorDiv.style.display = 'block';
}
var invalidField = validation.field === 'qty'
? row.querySelector('.bib-qty')
: row.querySelector('.bib-end');
if (invalidField) {
invalidField.focus();
}
return;
}
bibFetch('/ajax_bib_range.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body:
'action=save'
+ '&id=' + encodeURIComponent(id)
+ '&epr_id=' + encodeURIComponent(epr_id)
+ '&start=' + encodeURIComponent(start)
+ '&end=' + encodeURIComponent(end)
+ bibAjaxLangSuffix()
})
.then(res => res.text())
.then(raw => {
let data;
try {
data = JSON.parse(raw);
} catch (err) {
errorDiv.innerText = bibJs('jsServerError');
errorDiv.style.display = 'block';
return;
}
if (!data.success) {
errorDiv.innerText = data.message || bibJs('jsErrGeneric');
errorDiv.style.display = 'block';
return;
}
setBibContainerFromAjax(btnSave.closest('.epr-row'), data);
});
return;
}
// =====================
// VIEW
// =====================
let btnView = e.target.closest('.btn-view-range');
if (btnView) {
e.preventDefault();
let epr_id = btnView.dataset.eprId;
let range_id = btnView.dataset.rangeId;
console.log('epr_id:', epr_id);
console.log('range_id:', range_id);
if (!epr_id || typeof range_id === 'undefined') return;
let container = btnView.closest('.epr-block');
// Vérifier si une vue est déjà ouverte
let existing = document.querySelector('.epr-row-view');
// Toggle : si c'est le même œil qui a ouvert la vue, on la ferme et on s'arrête
if (existing
&& existing.dataset.eprId === epr_id
&& existing.dataset.rangeId === range_id
) {
existing.remove();
return;
}
// Un autre œil a été cliqué : fermer la vue précédente avant d'ouvrir la nouvelle
if (existing) {
existing.remove();
}
bibFetch('/ajax_bib_range.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body:
'action=view'
+ '&epr_id=' + encodeURIComponent(epr_id)
+ '&range_id=' + encodeURIComponent(range_id)
+ bibAjaxLangSuffix()
})
.then(res => res.text())
.then(raw => {
let data;
try {
data = JSON.parse(raw);
} catch (err) {
console.log(bibJs('jsServerError'));
return;
}
if (!data.success) {
console.log(data.message || bibJs('jsErrGeneric'));
return;
}
let row = btnView.closest('.epr-row');
// Injecter la nouvelle vue sous la ligne du bouton cliqué,
// en mémorisant epr_id et range_id pour le toggle suivant
row.insertAdjacentHTML('afterend', data.html);
// Stocker les identifiants sur la vue injectée pour pouvoir détecter
// le 2e clic sur le même œil
let newView = row.nextElementSibling;
if (newView && newView.classList.contains('epr-row-view')) {
newView.dataset.eprId = epr_id;
newView.dataset.rangeId = range_id;
}
});
return;
}
// =====================
// CLOSE VIEW
// =====================
let btnClose = e.target.closest('.btn-close-view');
if (btnClose) {
e.preventDefault();
let view = btnClose.closest('.epr-row-view');
if (view) {
view.remove();
}
return;
}
// =====================
// ASSIGN BATCH
// =====================
// Active/désactive le mode batch pour UNE épreuve.
// - Affiche les checkbox
// - Bloque Début/Fin
// - Affiche le bloc de configuration
// - Recalcule l’analyse initiale
// =====================
let btnBatch = e.target.closest('.btn-assign-batch');
if (btnBatch) {
e.preventDefault();
let row = btnBatch.closest('.epr-row');
if (!row) return;
// MSIN-4379 — Batch et auto sont mutuellement exclusifs.
if (row.classList.contains('auto-mode')) {
return;
}
let container = row.querySelector('.bib-container');
if (!container) return;
// OFF
if (row.classList.contains('batch-mode')) {
row.classList.remove('batch-mode');
row.querySelectorAll('.batch-select-range').forEach(cb => {
cb.disabled = false;
});
container.classList.remove('batch-mode');
row.querySelectorAll('.bib-start, .bib-qty, .bib-end').forEach(input => {
input.removeAttribute('readonly');
});
btnBatch.textContent = row.dataset.batchLabel || btnBatch.textContent;
let goBtn = row.querySelector('.btn-go-batch');
if (goBtn) {
goBtn.textContent = row.dataset.goLabel || goBtn.textContent;
}
row.querySelectorAll('.batch-select-range').forEach(cb => {
cb.checked = false;
});
let info = row.querySelector('.epr-actions .batch-info-text');
if (info) info.textContent = '';
syncBibUiState(row);
return;
}
// ON
row.classList.add('batch-mode');
container.classList.add('batch-mode');
row.querySelectorAll('.bib-start, .bib-qty, .bib-end').forEach(input => {
input.setAttribute('readonly', true);
});
btnBatch.textContent = row.dataset.batchLabelCancel || btnBatch.textContent;
let goBtn = row.querySelector('.btn-go-batch');
if (goBtn) {
goBtn.textContent = row.dataset.goLabel || goBtn.textContent;
}
if (typeof updateBatchAnalysis === 'function') {
updateBatchAnalysis(row);
}
syncBibUiState(row);
return;
}
// =====================
// SIMULER BATCH
// =====================
let btnSim = e.target.closest('.btn-simuler-batch');
if (btnSim) {
e.preventDefault();
let row = btnSim.closest('.epr-row');
if (!row) return;
let selected = [];
row.querySelectorAll('.batch-select-range:checked').forEach(cb => {
selected.push(cb.dataset.rangeId);
});
if (selected.length === 0) {
alert(bibJs('jsNoSeqSelected'));
return;
}
let isResetMode = row.dataset.mode === 'reset';
let sortKeys = bibGetRowSortKeys(row);
bibFetch('/ajax_bib_range.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body:
(isResetMode ? 'action=reset_preview' : 'action=batch_go')
+ '&epr_id=' + encodeURIComponent(row.dataset.eprId)
+ '&ranges=' + encodeURIComponent(JSON.stringify(selected))
+ bibAppendBatchSortParams('', sortKeys)
+ bibAjaxLangSuffix()
})
.then(res => res.json())
.then(data => {
if (!data.success) {
alert(data.message || bibJs('jsErrGeneric'));
return;
}
let existing = document.querySelector('.epr-row-view');
if (existing) {
existing.remove();
}
row.insertAdjacentHTML('afterend', data.html);
});
return;
}
// =====================
// RESET MODE
// =====================
let btnReset = e.target.closest('.btn-reset');
if (btnReset) {
e.preventDefault();
let row = btnReset.closest('.epr-row');
if (!row) return;
// MSIN-4379 — Reset et auto sont mutuellement exclusifs.
if (row.classList.contains('auto-mode')) {
return;
}
let container = row.querySelector('.bib-container');
if (!container) return;
// =====================
// OFF
// =====================
if (row.classList.contains('reset-mode')) {
row.classList.remove('reset-mode');
btnReset.textContent = row.dataset.resetLabel || btnReset.textContent;
container.classList.remove('batch-mode');
row.querySelectorAll('.bib-start, .bib-qty, .bib-end').forEach(input => {
input.removeAttribute('readonly');
});
row.querySelectorAll('.batch-select-range').forEach(cb => {
cb.checked = false;
});
let goBtn = row.querySelector('.btn-go-batch');
if (goBtn) {
goBtn.textContent = row.dataset.goLabel || goBtn.textContent;
}
let info = row.querySelector('.epr-actions .batch-info-text');
if (info) {
info.innerHTML = '';
}
row.dataset.mode = '';
syncBibUiState(row);
return;
}
// =====================
// ON
// =====================
row.classList.add('reset-mode');
btnReset.textContent = row.dataset.resetCancelLabel || btnReset.textContent;
row.dataset.mode = 'reset';
container.classList.add('batch-mode');
row.querySelectorAll('.bib-start, .bib-qty, .bib-end').forEach(input => {
input.setAttribute('readonly', true);
});
syncBibUiState(row);
let goBtn = row.querySelector('.btn-go-batch');
if (goBtn) {
goBtn.textContent = row.dataset.resetLabel || goBtn.textContent;
}
bibFetch('/ajax_bib_range.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body:
'action=refresh_ranges'
+ '&epr_id=' + encodeURIComponent(row.dataset.eprId)
+ '&mode=reset'
+ bibAjaxLangSuffix()
})
.then(res => res.json())
.then(data => {
if (!data.success) return;
let container = setBibContainerFromAjax(row, data);
if (!container) return;
container.classList.add('batch-mode');
row.querySelectorAll('.bib-start, .bib-qty, .bib-end').forEach(input => {
input.setAttribute('readonly', true);
});
syncBibUiState(row);
});
return;
}
// =====================
// GO BATCH
// =====================
let btnGo = e.target.closest('.btn-go-batch');
if (btnGo) {
e.preventDefault();
let row = btnGo.closest('.epr-row');
if (!row) return;
let selected = [];
row.querySelectorAll('.batch-select-range:checked').forEach(cb => {
selected.push(cb.dataset.rangeId);
});
if (selected.length === 0) {
alert(bibJs('jsNoSeqSelected'));
return;
}
let isResetMode = row.dataset.mode === 'reset';
let sortKeys = bibGetRowSortKeys(row);
if (isResetMode) {
bibFetch('/ajax_bib_range.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body:
'action=reset_apply'
+ '&epr_id=' + encodeURIComponent(row.dataset.eprId)
+ '&ranges=' + encodeURIComponent(JSON.stringify(selected))
+ bibAppendBatchSortParams('', sortKeys)
+ bibAjaxLangSuffix()
})
.then(res => res.json())
.then(data => {
if (!data.success) {
alert(data.message || bibJs('jsErrGeneric'));
return;
}
bibAfterBatchGoSuccess(row, data, true);
});
return;
}
bibRunBatchApplyChunks(row, selected, sortKeys);
return;
}
// =====================
// MSIN-4379 — Étape 2 : AUTO DOSSARD (clics Accepter / Annuler / Désactiver / Activer)
// Prochain tour : étape 6–7 (assignation PHP à l'inscription).
// =====================
let btnAccepterAuto = e.target.closest('.btn-accepter-auto');
if (btnAccepterAuto) {
e.preventDefault();
let row = btnAccepterAuto.closest('.epr-row');
if (!row) return;
let selected = [];
row.querySelectorAll('.batch-select-range:checked').forEach(cb => {
selected.push(cb.dataset.rangeId);
});
if (selected.length === 0) {
alert(bibJs('jsNoSeqSelected'));
return;
}
if (bibRowPendingBibs(row) > 0) {
bibAlertAutoPendingBibs(row);
return;
}
// MSIN-4379 — Persiste epr_bib_auto=1 sur les séquences choisies (save_auto_config).
bibFetch('/ajax_bib_range.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body:
'action=save_auto_config'
+ '&epr_id=' + encodeURIComponent(row.dataset.eprId)
+ '&active=1'
+ '&ranges=' + encodeURIComponent(JSON.stringify(selected))
+ bibAjaxLangSuffix()
})
.then(res => res.json())
.then(data => {
if (!data.success) {
alert(data.message || bibJs('jsErrGeneric'));
return;
}
syncAutoUiState(row, true);
exitAutoMode(row);
syncBibUiState(row);
});
return;
}
// MSIN-4379 — Annule l'édition sans appeler save_auto_config.
let btnAnnulerAuto = e.target.closest('.btn-annuler-auto');
if (btnAnnulerAuto) {
e.preventDefault();
let row = btnAnnulerAuto.closest('.epr-row');
if (!row) return;
exitAutoMode(row);
return;
}
// MSIN-4379 — Désactive l'auto en base (active=0, toutes les séquences à 0).
let btnDesactiverAuto = e.target.closest('.btn-desactiver-auto');
if (btnDesactiverAuto) {
e.preventDefault();
let row = btnDesactiverAuto.closest('.epr-row');
if (!row) return;
if (!confirm(bibJs('jsAutoDisableConfirm'))) {
return;
}
bibFetch('/ajax_bib_range.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body:
'action=save_auto_config'
+ '&epr_id=' + encodeURIComponent(row.dataset.eprId)
+ '&active=0'
+ '&ranges=' + encodeURIComponent('[]')
+ bibAjaxLangSuffix()
})
.then(res => res.json())
.then(data => {
if (!data.success) {
alert(data.message || bibJs('jsErrGeneric'));
return;
}
syncAutoUiState(row, false);
exitAutoMode(row);
syncBibUiState(row);
});
return;
}
// MSIN-4379 — Entrée dans le mode configuration auto.
let btnAuto = e.target.closest('.btn-auto');
if (btnAuto) {
e.preventDefault();
let row = btnAuto.closest('.epr-row');
if (!row) return;
if (row.classList.contains('batch-mode') || row.classList.contains('reset-mode')) {
return;
}
enterAutoMode(row);
return;
}
// =====================
// CREATE
// =====================
let btn = e.target.closest('.btn-add-range');
if (!btn) return;
e.preventDefault();
let container = btn.closest('.bib-container');
let errorDiv = container.querySelector('.bib-error-global');
// reset
if (errorDiv) {
errorDiv.style.display = 'none';
errorDiv.innerText = '';
}
let epr_id = btn.dataset.eprId;
if (!epr_id) return;
bibFetch('/ajax_bib_range.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: 'action=create&epr_id=' + encodeURIComponent(epr_id) + bibAjaxLangSuffix()
})
.then(res => res.text())
.then(raw => {
let data;
try {
data = JSON.parse(raw);
} catch (err) {
if (errorDiv) {
errorDiv.innerText = bibJs('jsServerError');
errorDiv.style.display = 'block';
}
return;
}
if (!data.success) {
console.log('CREATE ERROR:', data);
console.log('container:', container);
console.log('errorDiv:', errorDiv);
if (errorDiv) {
errorDiv.innerText = data.message || bibJs('jsErrGeneric');
errorDiv.style.display = 'block';
}
return;
}
setBibContainerFromAjax(btn.closest('.epr-row'), data);
});
});
function syncBibEventConfigHeaderNote() {
let chk = moduleBib.querySelector('.bib-event-allow-inter-epr');
if (!chk) {
return;
}
document.querySelectorAll('[data-bib-inter-epr-note]').forEach(function (note) {
note.classList.toggle('bib-ui-hidden', !chk.checked);
});
}
// MSIN-4424 — Autoriser mêmes numéros entre épreuves (réglage événement).
let chkAllowInterEpr = moduleBib.querySelector('.bib-event-allow-inter-epr');
if (chkAllowInterEpr) {
chkAllowInterEpr.addEventListener('change', function () {
let eveId = moduleBib.dataset.eveId || '';
if (!eveId) {
return;
}
bibFetch('/ajax_bib_range.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body:
'action=save_allow_inter_epr'
+ '&eve_id=' + encodeURIComponent(eveId)
+ '&allow=' + (chkAllowInterEpr.checked ? '1' : '0')
+ bibAjaxLangSuffix()
})
.then(function (res) { return res.json(); })
.then(function (data) {
if (!data.success) {
chkAllowInterEpr.checked = !chkAllowInterEpr.checked;
alert(data.message || bibJs('jsErrGeneric'));
return;
}
moduleBib.dataset.allowInterEpr = data.allow_inter_epr ? '1' : '0';
syncBibEventConfigHeaderNote();
let mount = document.getElementById('bib-anomalies-mount');
if (mount && data.anomalies_html) {
let blnWasActive = bibActiveTool === 'anomalies';
if (blnWasActive) {
bibRestoreToolContent('anomalies');
}
bibInvalidateToolSlot('anomalies');
mount.innerHTML = data.anomalies_html;
initModuleBibTippy(mount);
bibSyncToolNavBadges('anomalies');
bibRemountActiveToolAfterRefresh('anomalies');
}
if (bibQtySummaryShouldRefresh()) {
refreshBibQtySummaryPanel();
}
})
.catch(function () {
chkAllowInterEpr.checked = !chkAllowInterEpr.checked;
alert(bibJs('jsErrGeneric'));
});
});
}
// MSIN-4436 — Anomalies : coquille légère au chargement, détail en AJAX.
if (document.querySelector('#bib-anomalies-panel[data-bib-anomalies-deferred="1"]')) {
refreshBibAnomaliesPanel().then(function () {
bibSyncAllToolNavBadges();
bibApplyFocusFromUrlOnce();
});
} else {
bibSyncAllToolNavBadges();
bibApplyFocusFromUrlOnce();
}
}
})();