Files
ms1inscription-v5/js/v2/bib-assignments.js

5200 lines
216 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 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();
}
}
/**
* MSIN-4539 / MSIN-4550 — fetch ajax_bib_range.php.
* loader:true dès quun risque de délai (deferred / 1er paint) — voir projet/10-loader-coureur.mdc.
*/
function bibFetch(url, options, settings) {
settings = settings || {};
var useLoader = settings.loader === true;
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();
}
// MSIN-4528 — Reset : pas d'injection de grille (milliers de lignes = UI figée).
if (!isResetMode && data.html) {
row.insertAdjacentHTML('afterend', data.html);
}
if (isResetMode && data.message) {
let info = row.querySelector('.epr-actions .batch-info-text');
if (info) {
info.textContent = data.message;
}
}
// MSIN-4534 — Après GO : une seule paint (refresh lite + stats), pas de hop-hop menus.
options.skipAnomalies = true;
options.skipQtySummary = true;
options.refreshLite = true;
options.skipSync = true;
if (options.loader === undefined) {
options.loader = !isResetMode;
}
return 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;
});
// MSIN-4469 — Ne pas réouvrir les champs si impression verrouillée.
bibApplyRangeInputLockState(row);
// MSIN-4534 — Pas de syncBibUiState ici (stats encore stale → Réinit en retard).
var useLoader = options.loader !== false;
var skipAnomalies = options.skipAnomalies === true;
var skipQtySummary = options.skipQtySummary === true;
var refreshLite = options.refreshLite === true || isResetMode === true;
var skipSyncUntilStats = options.skipSync === 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,
skipQtySummary: skipQtySummary,
skipSync: skipSyncUntilStats
});
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 && stats.success) {
bibSyncEprBibStats(row, stats.info);
}
syncBibUiState(row);
});
});
}
function bibBatchSortMaxLevels() {
return 4;
}
function bibGetSortKeysFromRoot(root, classPrefix) {
var max = bibBatchSortMaxLevels();
var sorts = [];
var i;
var sel;
if (!root) {
for (i = 0; i < max; i++) {
sorts.push('');
}
return {
sorts: sorts,
sort1: '',
sort2: ''
};
}
for (i = 1; i <= max; i++) {
sel = root.querySelector('select[data-sort-level="' + i + '"]');
if (!sel && classPrefix) {
sel = root.querySelector(
i === 1
? 'select.' + classPrefix
: 'select.' + classPrefix + '-' + i
);
}
sorts.push(sel ? String(sel.value || '').trim() : '');
}
return {
sorts: sorts,
sort1: sorts[0] || '',
sort2: sorts[1] || ''
};
}
function bibGetRowSortKeys(row) {
return bibGetSortKeysFromRoot(row, 'batch-order');
}
function bibGetGlobalBatchSortKeys(panel) {
var keys = bibGetSortKeysFromRoot(panel, 'bib-global-batch-order');
if (!(keys.sort1 || '')) {
keys = bibGetSortKeysFromRoot(panel, 'bib-global-gen-batch-order');
}
return keys;
}
function bibAppendBatchSortParams(body, sortKeys) {
sortKeys = sortKeys || {};
var sorts = Array.isArray(sortKeys.sorts) ? sortKeys.sorts : null;
var max = bibBatchSortMaxLevels();
var i;
var out = body || '';
if (!sorts) {
sorts = [];
for (i = 1; i <= max; i++) {
sorts.push(sortKeys['sort' + i] || '');
}
}
for (i = 0; i < max; i++) {
out += '&sort_' + (i + 1) + '=' + encodeURIComponent(sorts[i] || '');
}
return out;
}
// MSIN-4379 — Mode équipe coché à l'écran (à envoyer avec Simuler / GO).
function bibGetRowTeamMode(row) {
if (!row) {
return '';
}
var checked = row.querySelector('.team-mode-box input[type="radio"]:checked');
return checked ? String(checked.value || '').trim() : '';
}
function bibAppendTeamModeParam(body, row) {
var teamMode = bibGetRowTeamMode(row);
if (!teamMode) {
return body || '';
}
return (body || '') + '&team_mode=' + encodeURIComponent(teamMode);
}
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)
+ bibAppendTeamModeParam('', row)
+ '&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) {
// MSIN-4534 — Attendre refresh+stats avant de baisser le loader (pas de hop-hop menus).
return bibAfterBatchGoSuccess(row, data, false, { loader: false })
.then(function () { return data; });
}
if (!deferUiRefresh) {
return bibAfterBatchGoRefreshOnly(row, false, {
loader: false,
skipAnomalies: true,
skipQtySummary: true,
refreshLite: true,
skipSync: true
}).then(function () { return data; });
}
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 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 = ''
+ '<div id="bib-global-batch"'
+ ' class="bib-global-batch bib-tool-panel"'
+ ' data-bib-tool="global_batch"'
+ ' data-global-batch-deferred="1">'
+ '<div class="bib-global-batch__body bib-ui-hidden"></div>'
+ '</div>';
}
}
function bibEscHtml(str) {
return String(str == null ? '' : str)
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;');
}
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 = '<div class="bib-global-batch-complete bib-global-batch-complete--'
+ bibEscHtml(state)
+ '" role="status" aria-live="polite">'
+ '<div class="bib-global-batch-complete__icon" aria-hidden="true">' + icon + '</div>'
+ '<h3 class="bib-global-batch-complete__title">' + bibEscHtml(title) + '</h3>'
+ '<p class="bib-global-batch-complete__message">' + bibEscHtml(message) + '</p>'
+ '<p class="bib-global-batch-complete__summary">' + bibEscHtml(summary) + '</p>'
+ '<button type="button" class="btn btn-primary bib-global-batch-complete__reload btn-global-batch-complete-reload">'
+ bibEscHtml(reloadLabel)
+ '</button>'
+ '</div>';
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;
bibSyncWorkspaceTabHighlight();
bibSyncWorkspaceSurfaceVisibility();
// MSIN-4546 — Charger Production seulement quand on ouvre cet espace.
if (workspaceId === 'production') {
bibEnsureProductionPanelLoaded().then(function () {
initBibProductionFieldsChooser(moduleBib);
});
}
// MSIN-4475 — Modes d'assignation : afficher les choix tout de suite (sans clic tuile).
if (workspaceId === 'operations' && options.keepTool !== true) {
var autoTool = panel.getAttribute('data-bib-auto-tool');
if (autoTool) {
bibOpenTool(autoTool);
}
}
}
var bibProductionLoadPromise = null;
/**
* MSIN-4546 — Onglet Production = page séparée : AJAX au 1er clic seulement.
*/
function bibEnsureProductionPanelLoaded() {
var panel = moduleBib.querySelector('[data-bib-workspace-panel="production"]');
var mount = document.getElementById('bib-production-mount');
if (!panel) {
return Promise.resolve();
}
// Déjà chargé (HTML production en place) → juste sassurer que le chooser est vivant.
if (panel.getAttribute('data-production-loaded') === '1' || !mount) {
initBibProductionFieldsChooser(panel);
return Promise.resolve(panel);
}
if (panel.getAttribute('data-production-deferred') !== '1'
&& mount.getAttribute('data-production-deferred') !== '1') {
initBibProductionFieldsChooser(panel);
return Promise.resolve(panel);
}
if (bibProductionLoadPromise) {
return bibProductionLoadPromise;
}
bibProductionLoadPromise = bibFetch('/ajax_bib_range.php', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: 'action=production_panel'
+ '&eve_id=' + encodeURIComponent(moduleBib.dataset.eveId || '')
+ bibAjaxLangSuffix()
}, { loader: true })
.then(function (res) { return res.json(); })
.then(function (data) {
if (!data || !data.success || !data.html) {
throw new Error((data && data.message) || bibJs('jsErrGeneric') || 'Erreur');
}
// Garder #bib-production-mount (innerHTML) pour ne pas perdre la cible derreur.
var liveMount = document.getElementById('bib-production-mount');
if (liveMount) {
liveMount.innerHTML = data.html;
liveMount.removeAttribute('data-production-deferred');
} else {
panel.innerHTML = data.html;
}
panel.removeAttribute('data-production-deferred');
panel.setAttribute('data-production-loaded', '1');
initModuleBibTippy(panel);
initBibProductionFieldsChooser(panel);
return panel;
})
.catch(function (err) {
var msg = (err && err.message) ? err.message : (bibJs('jsServerError') || 'Erreur serveur');
var errHost = document.getElementById('bib-production-mount') || panel;
if (errHost) {
errHost.innerHTML = '<div class="text-danger small" style="padding:12px;">'
+ bibTippyEscapeHtml(msg)
+ '</div>';
}
})
.finally(function () {
bibProductionLoadPromise = null;
});
return bibProductionLoadPromise;
}
/** MSIN-4512 — PDF ouvert : ne pas laisser longlet workspace allumé en parallèle. */
function bibSyncWorkspaceTabHighlight() {
var highlightWorkspace = (bibActiveTool === 'dist_print') ? null : bibActiveWorkspace;
moduleBib.querySelectorAll('.bib-workspace-tab').forEach(function (tab) {
var active = !!highlightWorkspace
&& tab.getAttribute('data-bib-workspace') === highlightWorkspace;
tab.classList.toggle('is-active', active);
tab.setAttribute('aria-selected', active ? 'true' : 'false');
});
}
/**
* MSIN-4512 — Une surface à la fois.
* PDF distribution : masquer espaces + épreuves (sinon lassignation reste sous le PDF).
* Autres cas : panneau de lespace actif + épreuves seulement en préparation.
*/
function bibSyncWorkspaceSurfaceVisibility() {
var blnPdfExclusive = (bibActiveTool === 'dist_print');
moduleBib.querySelectorAll('[data-bib-workspace-panel]').forEach(function (workspacePanel) {
var show = !blnPdfExclusive
&& workspacePanel.getAttribute('data-bib-workspace-panel') === bibActiveWorkspace;
workspacePanel.classList.toggle('bib-ui-hidden', !show);
});
var races = document.getElementById('bib-preparation-races');
if (races) {
races.classList.toggle(
'bib-ui-hidden',
blnPdfExclusive || bibActiveWorkspace !== 'preparation'
);
}
}
function bibWorkspaceForTool(toolId) {
if (toolId === 'event_config') {
return 'settings';
}
if (toolId === 'global_batch') {
return 'operations';
}
// MSIN-4470 / MSIN-4512 — PDF reste une action globale (mémorise lespace courant
// pour y revenir à la fermeture) mais la surface sous-jacente est masquée.
if (toolId === 'dist_print') {
return bibActiveWorkspace;
}
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 + '"]');
if (btn) {
titleEl.textContent = btn.getAttribute('data-bib-tool-label') || '';
return;
}
// MSIN-4475 — Titre depuis le panneau (outil ouvert auto, sans tuile).
var autoPanel = moduleBib.querySelector(
'[data-bib-workspace-panel][data-bib-auto-tool="' + toolId + '"]'
);
titleEl.textContent = autoPanel
? (autoPanel.getAttribute('data-bib-auto-tool-label') || '')
: '';
}
// MSIN-4470 — Le panneau PDF s'ouvre immédiatement sous la barre supérieure.
function bibPositionToolDetail(toolId) {
var detail = document.getElementById('bib-tool-detail');
var defaultSlot = document.getElementById('bib-tool-detail-default-slot');
if (!detail || !defaultSlot || !defaultSlot.parentNode) {
return;
}
if (toolId === 'dist_print') {
var firstWorkspacePanel = moduleBib.querySelector('[data-bib-workspace-panel]');
if (firstWorkspacePanel && firstWorkspacePanel.parentNode) {
firstWorkspacePanel.parentNode.insertBefore(detail, firstWorkspacePanel);
}
return;
}
defaultSlot.parentNode.insertBefore(detail, defaultSlot.nextSibling);
}
function bibCloseTool(options) {
options = options || {};
if (!bibActiveTool) {
return;
}
var closedTool = bibActiveTool;
bibRestoreToolContent(bibActiveTool);
bibInvalidateToolSlot(bibActiveTool);
bibActiveTool = null;
bibSetActiveToolButton(null);
bibSetToolDetailTitle(null);
bibSyncWorkspaceTabHighlight();
bibSyncWorkspaceSurfaceVisibility();
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');
}
bibPositionToolDetail(null);
// MSIN-4475 — Fermer les modes (plus de tuile) ramène à la préparation.
if (options.returnToPreparation === true
&& closedTool === 'global_batch'
&& bibActiveWorkspace === 'operations') {
bibSetWorkspace('preparation', { keepTool: true });
}
}
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 = '<span class="epr-header-summary bib-event-config-note bib-anomalies-nav-badge"'
+ ' data-bib-anomalies-nav-badge="1"'
+ ' data-bib-anomalies-nav-count="' + intCount + '"'
+ ' title="' + strLabel.replace(/"/g, '&quot;') + '">'
+ strLabel
+ '</span>';
}
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();
// MSIN-4550 — coureur dès le clic si chargement deferred possible (avant le fetch).
var panelPre = bibGetToolPanel(toolId);
var blnDeferredLoad = false;
if (toolId === 'dist_print' && panelPre
&& panelPre.getAttribute('data-bib-dist-print-deferred') === '1') {
blnDeferredLoad = true;
} else if (toolId === 'qty_summary' && panelPre
&& panelPre.getAttribute('data-bib-qty-summary-deferred') === '1') {
blnDeferredLoad = true;
} else if (toolId === 'global_batch' && panelPre
&& panelPre.getAttribute('data-global-batch-deferred') === '1') {
blnDeferredLoad = true;
}
if (blnDeferredLoad) {
bibLoaderShow();
}
return bibEnsureToolLoaded(toolId).then(function () {
var panel = bibGetToolPanel(toolId);
if (!panel || !bibMountToolContent(toolId)) {
return;
}
bibActiveTool = toolId;
bibSetActiveToolButton(toolId);
bibSetToolDetailTitle(toolId);
bibPositionToolDetail(toolId);
bibSyncWorkspaceTabHighlight();
bibSyncWorkspaceSurfaceVisibility();
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'));
}).finally(function () {
if (blnDeferredLoad) {
bibLoaderHide();
}
});
}
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()
}, { loader: true })
.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 genSectionLoaded = bibGetGlobalBatchGeneratedSection();
if (genSectionLoaded) {
bibBindGlobalGeneratedRange(genSectionLoaded);
}
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 bibCollectGlobalBatchGeneratedPending() {
var section = bibGetGlobalBatchGeneratedSection();
if (!section) {
return 0;
}
var total = 0;
section.querySelectorAll('.bib-global-gen-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 bibGetGlobalBatchGeneratedRangeFields(section) {
section = section || bibGetGlobalBatchGeneratedSection();
if (!section) {
return null;
}
var wrap = section.querySelector('.bib-global-gen-range');
if (!wrap) {
return null;
}
return {
wrap: wrap,
start: wrap.querySelector('.bib-global-gen-start'),
qty: wrap.querySelector('.bib-global-gen-qty'),
end: wrap.querySelector('.bib-global-gen-end'),
feedback: wrap.querySelector('.bib-global-gen-range__feedback'),
qtyEl: wrap.querySelector('.bib-global-gen-range__qty'),
dupesEl: wrap.querySelector('.bib-global-gen-range__dupes'),
autoEl: wrap.querySelector('.bib-global-gen-range__auto')
};
}
/** MSIN-4445 — Début obligatoire ; Fin/Qté optionnels (bounded=false → taille auto). */
function bibGetGlobalBatchGeneratedBounds(section) {
var fields = bibGetGlobalBatchGeneratedRangeFields(section);
if (!fields) {
return { start: 0, end: 0, qty: 0, bounded: false };
}
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) {
return { start: 0, end: 0, qty: 0, bounded: false };
}
if (pilot === 'qty' && qty > 0) {
end = start + qty - 1;
return { start: start, end: end, qty: qty, bounded: true };
}
if (pilot === 'end' && end >= start) {
qty = end - start + 1;
return { start: start, end: end, qty: qty, bounded: true };
}
return { start: start, end: 0, qty: 0, bounded: false };
}
function bibFormatGlobalGeneratedQtyFeedback(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 bibSetGlobalGeneratedDupesWarn(section, blnShow, strMessage) {
var fields = bibGetGlobalBatchGeneratedRangeFields(section);
if (!fields || !fields.dupesEl) {
return;
}
var msg = strMessage
|| bibJs('jsGlobalFreeDupesWarn')
|| 'Attention : vous êtes en train de créer des inscriptions avec des dossards en double.';
if (!blnShow) {
fields.dupesEl.textContent = '';
fields.dupesEl.classList.add('bib-ui-hidden');
} else {
fields.dupesEl.textContent = msg;
fields.dupesEl.classList.remove('bib-ui-hidden');
}
}
function bibUpdateGlobalGeneratedQtyFeedback(section) {
var fields = bibGetGlobalBatchGeneratedRangeFields(section);
if (!fields) {
return;
}
var bounds = bibGetGlobalBatchGeneratedBounds(section);
var pending = bibCollectGlobalBatchGeneratedPending();
var qtyEl = fields.qtyEl;
var autoEl = fields.autoEl;
if (autoEl) {
if (bounds.bounded) {
autoEl.classList.add('bib-ui-hidden');
} else {
autoEl.classList.remove('bib-ui-hidden');
}
}
if (!qtyEl) {
return;
}
qtyEl.classList.remove(
'bib-global-gen-range__feedback--juste',
'bib-global-gen-range__feedback--manquante',
'bib-global-gen-range__feedback--supplementaire'
);
if (!bounds.bounded) {
qtyEl.textContent = '';
bibSetGlobalGeneratedDupesWarn(section, false);
return;
}
var msg = bibFormatGlobalGeneratedQtyFeedback(bounds.qty, pending);
qtyEl.textContent = msg;
if (msg) {
if (bounds.qty === pending) {
qtyEl.classList.add('bib-global-gen-range__feedback--juste');
} else if (bounds.qty < pending) {
qtyEl.classList.add('bib-global-gen-range__feedback--manquante');
} else {
qtyEl.classList.add('bib-global-gen-range__feedback--supplementaire');
}
}
}
function bibSyncGlobalGeneratedRangeDerived(section) {
var fields = bibGetGlobalBatchGeneratedRangeFields(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 = '';
}
bibUpdateGlobalGeneratedQtyFeedback(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');
}
bibUpdateGlobalGeneratedQtyFeedback(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');
}
}
bibUpdateGlobalGeneratedQtyFeedback(section);
}
function bibPickGlobalGeneratedPilot(section, pilot) {
var fields = bibGetGlobalBatchGeneratedRangeFields(section);
if (!fields || !fields.wrap) {
return;
}
var start = bibRangeParseInt(fields.start && fields.start.value);
if (start <= 0) {
return;
}
fields.wrap.dataset.rangePilot = pilot;
bibSyncGlobalGeneratedRangeDerived(section);
var target = pilot === 'qty' ? fields.qty : fields.end;
if (target && !target.disabled) {
target.focus();
}
}
function bibBindGlobalGeneratedRange(section) {
var fields = bibGetGlobalBatchGeneratedRangeFields(section);
if (!fields || !fields.wrap || fields.wrap.dataset.bound === '1') {
return;
}
fields.wrap.dataset.bound = '1';
if (fields.start) {
fields.start.addEventListener('input', function () {
bibSyncGlobalGeneratedRangeDerived(section);
updateGlobalBatchGeneratedAnalysis();
});
}
if (fields.qty) {
fields.qty.addEventListener('focus', function () {
bibPickGlobalGeneratedPilot(section, 'qty');
});
fields.qty.addEventListener('click', function () {
bibPickGlobalGeneratedPilot(section, 'qty');
});
fields.qty.addEventListener('input', function () {
if (fields.wrap.dataset.rangePilot !== 'qty') {
fields.wrap.dataset.rangePilot = 'qty';
}
bibSyncGlobalGeneratedRangeDerived(section);
updateGlobalBatchGeneratedAnalysis();
});
}
if (fields.end) {
fields.end.addEventListener('focus', function () {
bibPickGlobalGeneratedPilot(section, 'end');
});
fields.end.addEventListener('click', function () {
bibPickGlobalGeneratedPilot(section, 'end');
});
fields.end.addEventListener('input', function () {
if (fields.wrap.dataset.rangePilot !== 'end') {
fields.wrap.dataset.rangePilot = 'end';
}
bibSyncGlobalGeneratedRangeDerived(section);
updateGlobalBatchGeneratedAnalysis();
});
}
bibSyncGlobalGeneratedRangeDerived(section);
}
function bibAppendGlobalBatchGeneratedParams(body, section) {
var sortKeys = bibGetGlobalBatchSortKeys(section);
var bounds = bibGetGlobalBatchGeneratedBounds(section);
body = bibAppendBatchSortParams(body, sortKeys);
body += '&start_bib=' + encodeURIComponent(bounds.start);
body += '&end_bib=' + encodeURIComponent(bounds.bounded ? bounds.end : 0);
body += '&epr_ids=' + encodeURIComponent(JSON.stringify(bibCollectGlobalBatchGeneratedEprIds()));
return body;
}
function updateGlobalBatchGeneratedAnalysis() {
var section = bibGetGlobalBatchGeneratedSection();
if (!section) {
return Promise.resolve();
}
bibBindGlobalGeneratedRange(section);
var infoEl = section.querySelector('.bib-global-gen-batch__info');
var eprIds = bibCollectGlobalBatchGeneratedEprIds();
var bounds = bibGetGlobalBatchGeneratedBounds(section);
bibUpdateGlobalGeneratedQtyFeedback(section);
if (!infoEl) {
return Promise.resolve();
}
if (eprIds.length === 0) {
bibSetGlobalBatchInfo(
infoEl,
bibJs('jsGlobalNoEpr') || bibJs('jsBatchNone'),
'error'
);
bibSetGlobalGeneratedDupesWarn(section, false);
return Promise.resolve(null);
}
if (bounds.start <= 0) {
bibSetGlobalBatchInfo(
infoEl,
bibJs('jsGlobalGenNoStart') || bibJs('jsFieldsRequired'),
'error'
);
bibSetGlobalGeneratedDupesWarn(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: 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'
);
bibSetGlobalGeneratedDupesWarn(section, false);
return data;
}
bibSetGlobalBatchInfo(infoEl, data.info || '', 'normal');
if (data.duplicates && data.duplicates.has) {
bibSetGlobalGeneratedDupesWarn(section, true, data.duplicates.message || '');
} else {
bibSetGlobalGeneratedDupesWarn(section, false);
}
return data;
})
.catch(function () {
bibSetGlobalBatchInfo(infoEl, bibJs('jsErrGeneric'), 'error');
return null;
});
}
function bibRunGlobalBatchGeneratedGo() {
var section = bibGetGlobalBatchGeneratedSection();
if (!section) {
return;
}
var eprIds = bibCollectGlobalBatchGeneratedEprIds();
var bounds = bibGetGlobalBatchGeneratedBounds(section);
var sortKeys = bibGetGlobalBatchSortKeys(section);
if (eprIds.length === 0) {
alert(bibJs('jsGlobalNoEpr') || bibJs('jsBatchNone'));
return;
}
if (bounds.start <= 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,
skipQtySummary: true,
refreshLite: true,
skipSync: 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();
});
}
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,
skipQtySummary: true,
refreshLite: true,
skipSync: 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'));
});
// MSIN-4469 — Le téléchargement part dans un nouvel onglet;
// lécran principal revient aussitôt à Quantités et assignation.
// MSIN-4515 — Serialize data-item-key / data-item-side via UI kit chooser.
function bibProdFieldsPanel() {
return moduleBib.querySelector('.bib-production-fields');
}
function bibProdFieldsChooser() {
var panel = bibProdFieldsPanel();
if (!panel) {
return null;
}
return panel.querySelector('.ms1-ui-chooser[data-ms1-ui-screen="bib-prod-fields"]')
|| panel.querySelector('.ms1-ui-chooser');
}
function bibProdFieldsLabel(attr, fallback) {
var panel = bibProdFieldsPanel();
var val = panel ? panel.getAttribute(attr) : '';
return val || fallback;
}
function bibProdEscapeHtml(str) {
return String(str == null ? '' : str)
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;');
}
function bibProdFieldsBuildPayload() {
var payload = {};
var chooser = bibProdFieldsChooser();
if (!chooser) {
return payload;
}
chooser.querySelectorAll('.ms1-ui-chooser-section[data-section-id]').forEach(function (section) {
var eprId = section.getAttribute('data-section-id') || '';
if (!eprId) {
return;
}
var rows = [];
section.querySelectorAll('.ms1-ui-chooser-selected-item').forEach(function (row) {
var key = String(row.getAttribute('data-item-key') || '');
var side = String(row.getAttribute('data-item-side') || '');
if (!key || !side) {
return;
}
rows.push({ key: key, side: side });
});
payload[eprId] = rows;
});
return payload;
}
function bibProdFieldsSerializeBody() {
return '&fields_json=' + encodeURIComponent(JSON.stringify(bibProdFieldsBuildPayload()));
}
function bibProdFieldsStatusMsg() {
var panel = bibProdFieldsPanel();
return panel ? panel.querySelector('.bib-production-fields-save-msg') : null;
}
// MSIN-4515 — Persist auto immédiat (JSON) ; alerte si échec.
var bibProdFieldsSaveTimer = null;
function bibProdFieldsSaveNow(statusText) {
var fieldsPanel = bibProdFieldsPanel();
if (!fieldsPanel || fieldsPanel.getAttribute('data-locked') === '1') {
return;
}
var eveId = fieldsPanel.getAttribute('data-eve-id') || '';
if (!eveId) {
return;
}
var msg = bibProdFieldsStatusMsg();
var body = 'action=production_fields_save'
+ '&eve_id=' + encodeURIComponent(eveId)
+ bibAjaxLangSuffix()
+ bibProdFieldsSerializeBody();
fetch('/ajax_bib_range.php', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' },
body: body,
credentials: 'same-origin'
})
.then(function (res) { return res.json(); })
.then(function (result) {
if (result && result.success) {
if (msg) {
msg.textContent = statusText
|| bibProdFieldsLabel('data-label-saved', 'Enregistré.');
}
return;
}
var err = (result && result.message)
|| (bibJs('jsErrGeneric') || 'Erreur');
if (msg) {
msg.textContent = err;
}
alert(err);
})
.catch(function () {
var err = bibJs('jsServerError')
|| bibJs('jsErrGeneric')
|| 'Erreur serveur';
if (msg) {
msg.textContent = err;
}
alert(err);
});
}
function bibProdFieldsSaveSoon(statusText) {
if (bibProdFieldsSaveTimer) {
clearTimeout(bibProdFieldsSaveTimer);
}
bibProdFieldsSaveTimer = setTimeout(function () {
bibProdFieldsSaveTimer = null;
bibProdFieldsSaveNow(statusText);
}, 0);
}
/** MSIN-4515 — mockup A + Face/Endos/Info via MS1UiChooser (réessaie si script pas prêt). */
function initBibProductionFieldsChooser(root) {
var scope = (root && root.querySelector) ? root : moduleBib;
var fieldsPanel = scope.querySelector('.bib-production-fields')
|| moduleBib.querySelector('.bib-production-fields');
if (!fieldsPanel) {
return false;
}
var chooser = fieldsPanel.querySelector('.ms1-ui-chooser[data-ms1-ui-screen="bib-prod-fields"]')
|| fieldsPanel.querySelector('.ms1-ui-chooser');
if (!chooser) {
return false;
}
// Déjà branché et vivant.
if (chooser._ms1UiChooser) {
return true;
}
if (!window.MS1UiChooser || typeof window.MS1UiChooser.init !== 'function') {
if (!fieldsPanel.getAttribute('data-bib-prod-chooser-retry')) {
fieldsPanel.setAttribute('data-bib-prod-chooser-retry', '1');
window.setTimeout(function () {
fieldsPanel.removeAttribute('data-bib-prod-chooser-retry');
initBibProductionFieldsChooser(scope);
}, 120);
}
return false;
}
var sideOptions = [];
try {
sideOptions = JSON.parse(chooser.getAttribute('data-side-options') || '[]');
} catch (err) {
sideOptions = [];
}
var blnLocked = fieldsPanel.getAttribute('data-locked') === '1'
|| chooser.getAttribute('data-locked') === '1'
|| chooser.getAttribute('data-side-locked') === '1';
try {
chooser.removeAttribute('data-ms1-ui-chooser-init');
chooser._ms1UiChooser = null;
window.MS1UiChooser.init(chooser, {
getBudget: function () { return null; },
labelRemove: fieldsPanel.getAttribute('data-label-remove') || '',
sideOptions: sideOptions,
defaultSide: chooser.getAttribute('data-default-side') || 'face',
sideLocked: blnLocked,
onChange: function (_root, reason) {
if (fieldsPanel.getAttribute('data-locked') === '1') {
return;
}
if (reason === 'apply') {
bibProdFieldsSaveNow(bibProdFieldsLabel(
'data-label-apply-done',
'Choix de la 1re épreuve appliqués aux autres.'
));
return;
}
bibProdFieldsSaveSoon();
}
});
} catch (errInit) {
chooser.removeAttribute('data-ms1-ui-chooser-init');
chooser._ms1UiChooser = null;
return false;
}
return !!chooser._ms1UiChooser;
}
var bibProdPanelPollTimer = null;
var bibProdPanelPollAttempts = 0;
function bibProdStopPanelPoll() {
if (bibProdPanelPollTimer) {
clearTimeout(bibProdPanelPollTimer);
bibProdPanelPollTimer = null;
}
bibProdPanelPollAttempts = 0;
}
/** MSIN-4515 — Recharge le panneau Production (Télécharger / Déverrouiller) sans F5. */
function bibProdReloadProductionPanelHtml() {
var panel = moduleBib.querySelector('[data-bib-workspace-panel="production"]');
var mount = document.getElementById('bib-production-mount');
if (!panel || !mount) {
return Promise.resolve(false);
}
return bibFetch('/ajax_bib_range.php', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: 'action=production_panel'
+ '&eve_id=' + encodeURIComponent(moduleBib.dataset.eveId || '')
+ bibAjaxLangSuffix()
}, { loader: false })
.then(function (res) { return res.json(); })
.then(function (data) {
if (!data || !data.success || !data.html) {
return false;
}
mount.innerHTML = data.html;
panel.setAttribute('data-production-loaded', '1');
initModuleBibTippy(panel);
initBibProductionFieldsChooser(panel);
return true;
})
.catch(function () {
return false;
});
}
/**
* MSIN-4515 — Après generate : poll jusquà voir Déverrouiller (+ Télécharger quand prêt).
*/
function bibProdPollProductionPanelAfterGenerate() {
bibProdStopPanelPoll();
bibProdPanelPollAttempts = 0;
function schedule(ms) {
bibProdPanelPollTimer = setTimeout(run, ms);
}
function run() {
bibProdPanelPollAttempts += 1;
bibProdReloadProductionPanelHtml().then(function (ok) {
var mount = document.getElementById('bib-production-mount');
if (!mount) {
return;
}
var hasUnlock = !!mount.querySelector('input[name="action"][value="development_unlock"]');
var hasDownload = !!mount.querySelector('input[name="action"][value="download"]');
var stillGenerate = !!mount.querySelector('#bib-production-generate-form');
if (hasUnlock || hasDownload) {
if (hasDownload || bibProdPanelPollAttempts >= 36) {
bibProdStopPanelPoll();
return;
}
// Verrouillé mais Excel encore « generating » → continuer jusquau download.
schedule(2500);
return;
}
if (stillGenerate && bibProdPanelPollAttempts < 36) {
schedule(2500);
return;
}
if (bibProdPanelPollAttempts < 36) {
schedule(2500);
return;
}
bibProdStopPanelPoll();
});
}
// Premier refresh rapidement (commande déjà créée / verrou en BD).
schedule(1200);
}
moduleBib.addEventListener('submit', function (e) {
var productionForm = e.target.closest('.bib-production-return-preparation-form');
if (productionForm && moduleBib.contains(productionForm)) {
// MSIN-4515 / MSIN-4469 — Générer Excel (target=_blank).
// IMPORTANT : ne PAS retirer le form / disable le bouton pendant le submit
// (ça annulait le POST → flash reload + aucun fichier).
if (productionForm.classList.contains('bib-production-generate-form')) {
if (productionForm.getAttribute('data-submitted') === '1') {
e.preventDefault();
return;
}
productionForm.setAttribute('data-submitted', '1');
var host = productionForm.querySelector('.bib-production-generate-fields-host');
if (host) {
host.innerHTML = '';
var hidden = document.createElement('input');
hidden.type = 'hidden';
hidden.name = 'fields_json';
hidden.value = JSON.stringify(bibProdFieldsBuildPayload());
host.appendChild(hidden);
}
// Après que le navigateur ait lancé le POST vers le nouvel onglet.
setTimeout(function () {
var genBtn = productionForm.querySelector('button[type="submit"]');
if (genBtn) {
genBtn.disabled = true;
}
bibProdUiMarkLockedAfterGenerate(false);
bibProdPollProductionPanelAfterGenerate();
}, 0);
try {
window.sessionStorage.setItem('ms1_bib_workspace', 'production');
} catch (errWs) { /* ignore */ }
}
bibSetWorkspace('production');
}
});
/**
* MSIN-4515 — Verrouille lUI locale après generate.
* @param {boolean} blnRemoveForm — false pendant submit (garder le form pour le POST).
*/
function bibProdUiMarkLockedAfterGenerate(blnRemoveForm) {
var genForm = moduleBib.querySelector('#bib-production-generate-form');
if (genForm && blnRemoveForm) {
var lockedHtml = '<p class="bib-production-category__status">'
+ '<i class="fa fa-lock mr-1" aria-hidden="true"></i>'
+ bibProdEscapeHtml(bibProdFieldsLabel(
'data-label-excel-locked',
'En impression — séquences verrouillées'
))
+ '</p>';
genForm.insertAdjacentHTML('beforebegin', lockedHtml);
genForm.remove();
} else if (genForm && !blnRemoveForm) {
var status = genForm.previousElementSibling;
if (!status || !status.classList.contains('bib-production-category__status')) {
genForm.insertAdjacentHTML(
'beforebegin',
'<p class="bib-production-category__status">'
+ '<i class="fa fa-lock mr-1" aria-hidden="true"></i>'
+ bibProdEscapeHtml(bibProdFieldsLabel(
'data-label-excel-locked',
'En impression — séquences verrouillées'
))
+ '</p>'
);
}
genForm.style.display = 'none';
}
var fieldsPanel = bibProdFieldsPanel();
if (fieldsPanel) {
fieldsPanel.setAttribute('data-locked', '1');
}
var chooser = bibProdFieldsChooser();
if (chooser) {
chooser.setAttribute('data-locked', '1');
chooser.setAttribute('data-side-locked', '1');
}
moduleBib.querySelectorAll(
'.ms1-ui-chooser-apply-all, .ms1-ui-chooser-selected-remove, .ms1-ui-chooser-chip'
).forEach(function (el) {
if (fieldsPanel && fieldsPanel.contains(el)) {
el.remove();
}
});
}
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({ returnToPreparation: true });
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 genBounds = bibGetGlobalBatchGeneratedBounds(genSection);
if (eprIds.length === 0) {
alert(bibJs('jsGlobalNoEpr') || bibJs('jsBatchNone'));
return;
}
if (genBounds.start <= 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;
}
});
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-batch-order-3, .bib-global-batch-order-4,'
+ ' .bib-global-gen-epr-select, .bib-global-gen-batch-order, .bib-global-gen-batch-order-2,'
+ ' .bib-global-gen-batch-order-3, .bib-global-gen-batch-order-4,'
+ ' .bib-global-gen-start, .bib-global-gen-qty, .bib-global-gen-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;
}
});
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-4469 — Cadenas impression (bleu) a préséance sur le cadenas humain. */
function bibRowIsProductionLocked(row) {
if (!row) {
return false;
}
if (row.getAttribute('data-production-locked') === '1') {
return true;
}
return !!row.querySelector('.btn-bib-production-lock, .bib-range[data-production-locked="1"]');
}
function bibAlertProductionLocked() {
alert(bibJsConfirm('jsProductionLocked'));
}
/** Remet readonly seulement là où le verrou (humain ou impression) s'applique. */
function bibApplyRangeInputLockState(row) {
if (!row) {
return;
}
row.querySelectorAll('.bib-range.epr-line').forEach(function (line) {
var locked = line.dataset.locked === '1';
line.querySelectorAll('.bib-start, .bib-qty, .bib-end').forEach(function (input) {
if (locked) {
input.setAttribute('readonly', 'readonly');
} else {
input.removeAttribute('readonly');
}
});
});
}
// MSIN-4468 — Met à jour la capacité totale éditable et la disponibilité calculée.
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 elTotale = document.getElementById('qte_totale_' + 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 (elTotale) {
elTotale.value = row.qte_courante;
}
if (elCourante) {
elCourante.textContent = row.qte_courante;
}
if (elInscrits) {
elInscrits.textContent = row.qte_inscrits;
}
let gestionPanel = document.querySelector(
'.epr-gestion-panel[data-epr-id="' + eprId + '"]'
);
if (gestionPanel && row.qte_inscrits !== undefined) {
gestionPanel.dataset.qteInscrits = row.qte_inscrits;
}
if (elCheckin) {
elCheckin.textContent = row.qte_checkin;
}
if (elRestante) {
elRestante.textContent = 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 btnQteTotal = document.querySelector(
'.epr-gestion-panel[data-epr-id="' + eprId + '"] .btn_qte_total'
);
if (btnQteTotal) {
btnQteTotal.setAttribute('data-qte_initiale', row.qte_courante);
}
});
}
function bibSaveQteTotal(btn) {
let eprId = btn.getAttribute('data-epr_id');
if (!eprId) {
return;
}
let input = document.getElementById('qte_totale_' + eprId);
if (!input) {
return;
}
let strQteTotale = String(input.value || '').trim();
let intQteTotale = Number(strQteTotale);
if (!/^\d+$/.test(strQteTotale)
|| !Number.isSafeInteger(intQteTotale)
|| intQteTotale > 9999999) {
// MSIN-4479 — data-js-err-generic → dataset.jsErrGeneric
alert(bibJs('jsErrGeneric') || 'Erreur');
return;
}
let gestionPanel = btn.closest('.epr-gestion-panel');
let intNbInscriptions = gestionPanel
? parseInt(gestionPanel.dataset.qteInscrits, 10) || 0
: 0;
if (intQteTotale < intNbInscriptions) {
alert(bibJsFmt('jsQteTotalMin', intNbInscriptions));
return;
}
bibLoaderShow();
fetch('/ajax_promoteur.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
credentials: 'same-origin',
body:
'a=qte_total'
+ '&epr_id=' + encodeURIComponent(eprId)
+ '&total=' + encodeURIComponent(intQteTotale)
+ '&lang=' + encodeURIComponent(moduleBib.dataset.lang || 'fr')
+ '&csrf_token=' + encodeURIComponent(moduleBib.dataset.csrfToken || '')
})
.then(function (res) {
return res.json();
})
.then(function (result) {
if (result && result.state === 'success' && result.data) {
bibApplyQteData(result.data);
return;
}
alert((result && result.message) || bibJs('jsErrGeneric') || 'Erreur');
})
.catch(function () {
alert(bibJs('jsServerError') || bibJs('jsErrGeneric') || 'Erreur serveur');
})
.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);
// MSIN-4546 — Détail épreuve chargé à la première ouverture.
if (willExpand) {
bibEnsureRaceDetailLoaded(row);
}
}
/**
* MSIN-4546 — Charge le panneau éditable d'une épreuve (1re ouverture).
*/
function bibEnsureRaceDetailLoaded(row) {
if (!row || !moduleBib) {
return Promise.resolve();
}
if (row.getAttribute('data-race-detail-deferred') !== '1') {
return Promise.resolve();
}
if (row.getAttribute('data-race-detail-loading') === '1'
|| row.getAttribute('data-race-detail-loaded') === '1') {
return Promise.resolve();
}
var mount = row.querySelector('[data-race-detail-mount="1"]');
var eprId = row.getAttribute('data-epr-id') || '';
var eveId = moduleBib.dataset.eveId || '';
if (!mount || !eprId) {
return Promise.resolve();
}
row.setAttribute('data-race-detail-loading', '1');
return bibFetch('/ajax_bib_range.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: 'action=race_detail'
+ '&epr_id=' + encodeURIComponent(eprId)
+ '&eve_id=' + encodeURIComponent(eveId)
+ bibAjaxLangSuffix()
}, { loader: false })
.then(function (res) { return res.json(); })
.then(function (data) {
if (!data || !data.success || !data.html) {
throw new Error((data && data.message) || bibJs('jsErrGeneric') || 'Erreur');
}
mount.innerHTML = data.html;
mount.removeAttribute('data-race-detail-deferred');
row.removeAttribute('data-race-detail-deferred');
row.setAttribute('data-race-detail-loaded', '1');
if (typeof data.auto_active !== 'undefined') {
row.setAttribute('data-auto-active', data.auto_active ? '1' : '0');
row.classList.toggle('auto-enabled', !!data.auto_active);
}
if (typeof data.a_assigner !== 'undefined') {
row.setAttribute('data-bib-a-assigner', String(data.a_assigner));
}
initModuleBibTippy(mount);
initBibRangeRows(mount);
syncBibUiState(row);
})
.catch(function (err) {
var msg = (err && err.message) ? err.message : (bibJs('jsServerError') || 'Erreur serveur');
mount.innerHTML = '<div class="text-danger small" style="padding:12px;">'
+ bibTippyEscapeHtml(msg)
+ '</div>';
})
.finally(function () {
row.removeAttribute('data-race-detail-loading');
});
}
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, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;');
}
function bibTippyAideContent(reference) {
let span = reference.querySelector('.bib-aide-text');
if (!span) {
return '';
}
// Mini-formatage : retours à la ligne → <br> ; 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 += '<p>' + para.join('<br>') + '</p>';
para = [];
}
} else {
para.push(bibTippyEscapeHtml(line));
}
});
if (para.length) {
html += '<p>' + para.join('<br>') + '</p>';
}
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);
}
}
}
}
/** MSIN-4530 — Comme bibSetVisible, mais pour tous les matches (ex. 4 niveaux de tri). */
function bibSetVisibleAll(selector, show, row) {
let root = row || moduleBib;
if (!root || !selector) {
return;
}
root.querySelectorAll(selector).forEach(function (el) {
el.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) {
// MSIN-4526 — Ignorer les cases masquées (autre mode).
return Array.from(row.querySelectorAll('.batch-select-range:checked')).filter(function (cb) {
let wrap = cb.closest('.batch-checkbox');
return wrap && !wrap.classList.contains('bib-ui-hidden');
}).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: true })
.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 / MSIN-4512 — mockup A via MS1UiChooser + SortableJS. */
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 chooser = panel.querySelector('.ms1-ui-chooser[data-ms1-ui-screen="bib-dist-print"]')
|| panel.querySelector('.ms1-ui-chooser');
if (!chooser || !window.MS1UiChooser || typeof window.MS1UiChooser.init !== 'function') {
return;
}
function bibDistPrintBudget() {
let radio = chooser.querySelector('.bib-dist-print-orient-radio:checked, .ms1-ui-chooser-radio:checked');
let orient = radio ? String(radio.value || 'P') : 'P';
let budget = parseInt(
chooser.getAttribute(orient === 'L' ? 'data-budget-l' : 'data-budget-p')
|| panel.getAttribute(orient === 'L' ? 'data-budget-l' : 'data-budget-p')
|| '0',
10
);
return budget > 0 ? budget : 100;
}
window.MS1UiChooser.init(chooser, {
getBudget: bibDistPrintBudget,
radioSelector: '.bib-dist-print-orient-radio, .ms1-ui-chooser-radio',
labelRemove: panel.getAttribute('data-label-remove') || '',
fitUsedTpl: panel.getAttribute('data-fit-used-tpl') || '',
fitOver: panel.getAttribute('data-fit-over') || '',
fitFull: panel.getAttribute('data-fit-full') || ''
});
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: true })
.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);
}
// MSIN-4534 — skipSync : différer syncBibUiState jusqu'aux stats finales (évite menus en retard).
if (!opts.skipSync) {
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);
// MSIN-4515 — Après génération Excel + reload : reprendre lespace Production.
try {
var storedWs = window.sessionStorage.getItem('ms1_bib_workspace') || '';
if (storedWs === 'production' || storedWs === 'operations'
|| storedWs === 'settings' || storedWs === 'preparation') {
window.sessionStorage.removeItem('ms1_bib_workspace');
bibSetWorkspace(storedWs);
}
} catch (errRestoreWs) { /* ignore */ }
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-4564 — Quitte batch ou reset (bouton Fermer en bas). */
function exitBatchOrResetMode(row) {
if (!row) return;
let isReset = row.classList.contains('reset-mode');
let container = row.querySelector('.bib-container');
if (isReset) {
row.classList.remove('reset-mode');
row.dataset.mode = '';
let btnReset = row.querySelector('.btn-reset');
if (btnReset) {
btnReset.textContent = row.dataset.resetLabel || btnReset.textContent;
}
} else {
row.classList.remove('batch-mode');
let btnBatch = row.querySelector('.btn-assign-batch');
if (btnBatch) {
btnBatch.textContent = row.dataset.batchLabel || btnBatch.textContent;
}
}
if (container) {
container.classList.remove('batch-mode');
}
row.querySelectorAll('.bib-start, .bib-qty, .bib-end').forEach(function (input) {
input.removeAttribute('readonly');
});
row.querySelectorAll('.batch-select-range').forEach(function (cb) {
cb.checked = false;
cb.disabled = 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.textContent = '';
info.innerHTML = '';
}
bibApplyRangeInputLockState(row);
syncBibUiState(row);
}
/** MSIN-4379 — Quitte le mode édition auto sans sauver. MSIN-4526 — local, sans refresh_ranges. */
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');
});
row.querySelectorAll('.batch-select-range').forEach(function (cb) {
cb.checked = false;
});
bibApplyRangeInputLockState(row);
syncBibUiState(row);
}
/** MSIN-4379 — Ouvre le mode édition auto. MSIN-4526 — local, sans refresh_ranges. */
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);
});
bibSyncModeRangeCheckboxes(row, { precheckAuto: 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 hasAssignLock = row.querySelector('.btn-bib-commande-lock--assign') !== null;
btn.disabled = hasAssignLock || bibRowIsProductionLocked(row);
}
/**
* MSIN-4526 — Affiche/masque les cases séquence selon le mode, sans AJAX.
* Assign/auto : dispo > 0. Reset : utilisés > 0.
* @param {HTMLElement} row
* @param {{precheckAuto?: boolean}} [opts]
*/
function bibSyncModeRangeCheckboxes(row, opts) {
opts = opts || {};
if (!row) {
return;
}
let modes = bibRowModes(row);
let inPickFlow = modes.batch || modes.reset || modes.auto;
row.querySelectorAll('.bib-range.epr-line').forEach(function (line) {
let wrap = line.querySelector('.batch-checkbox');
let cb = line.querySelector('.batch-select-range');
if (!wrap || !cb) {
return;
}
// MSIN-4577 — Cases assign/reset : le cadenas commande ne masque pas lassignation.
if (!inPickFlow) {
wrap.classList.add('bib-ui-hidden');
cb.checked = false;
return;
}
let used = parseInt((line.querySelector('.bib-used')?.textContent || '0'), 10) || 0;
let dispo = parseInt((line.querySelector('.bib-dispo')?.textContent || '0'), 10) || 0;
let show = modes.reset ? (used > 0) : (dispo > 0);
if (!show) {
wrap.classList.add('bib-ui-hidden');
cb.checked = false;
return;
}
wrap.classList.remove('bib-ui-hidden');
if (opts.precheckAuto && modes.auto && line.dataset.bibAuto === '1') {
cb.checked = true;
}
});
}
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;
}
});
// MSIN-4564 — Pendant le flux, masquer les boutons méthode (Fermer / Annuler en bas).
let showResetBtn = hasSequences && avecBib > 0
&& !modes.auto && !modes.batch && !modes.reset;
bibSetVisible('.bib-assignment-methods', !inPickFlow, row);
bibSetVisible('.bib-advanced-actions', showResetBtn, row);
bibSetVisible('.epr-action-batch-group',
hasSequences && !modes.reset && !modes.auto && !modes.batch, row);
bibSetVisible('.epr-action-reset-group', showResetBtn, 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);
bibSyncModeRangeCheckboxes(row);
hasSelection = bibCountSelectedRanges(row) > 0;
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);
// MSIN-4564 — Annuler = auto seulement ; Fermer = batch / reset.
bibSetVisible('.epr-action-cancel-auto-group', inAutoFlow && hasSequences, row);
bibSetVisible('.epr-action-close-batch-group', inBatchFlow && hasSequences, row);
bibSetVisible('.epr-action-accept-auto-group', showAutoReady, row);
bibSetVisible('.epr-auto-info-group', showAutoReady, row);
bibSetVisible('.batch-reset-warning', showBatchReady && modes.reset, row);
// MSIN-4530 — Tous les wraps de tri (pas seulement le 1er via querySelector).
// MSIN-4530 — tous les niveaux (14) ; reset = aucun tri. Pas de repli partiel.
let showSorts = showBatchReady && !modes.reset;
bibSetVisibleAll('.epr-batch-order-wrap', showSorts, row);
bibSetVisible('.epr-action-sim-group', showSorts, 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;
}
// MSIN-4526 — Plus de refresh_ranges à chaque coche (CTE trous + rebuild HTML).
let existing = document.querySelector('.epr-row-view');
if (existing) {
existing.remove();
}
updateBatchAnalysis(row);
syncBibUiState(row);
});
moduleBib.querySelectorAll('.epr-row').forEach(syncBibUiState);
moduleBib.addEventListener('click', function (e) {
let btnQteTotal = e.target.closest('.btn_qte_total');
if (btnQteTotal && moduleBib.contains(btnQteTotal)) {
e.preventDefault();
bibSaveQteTotal(btnQteTotal);
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;
// MSIN-4469 — Impression : pas de bascule du cadenas humain.
if (btnLock.disabled || bibRowIsProductionLocked(row)) {
bibAlertProductionLocked();
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 (bibRowIsProductionLocked(row)) {
bibAlertProductionLocked();
return;
}
if (btnResetAllEpr.disabled) {
alert(bibJsConfirm('jsResetAllLocked'));
return;
}
if (row.querySelector('.btn-bib-commande-lock--assign')) {
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()
}, { loader: true })
.then(res => res.json())
.then(data => {
if (!data.success) {
alert(data.message || bibJs('jsErrGeneric'));
return;
}
// MSIN-4528 — même chemin que reset séquence (pas de grille HTML).
return bibAfterBatchGoSuccess(row, data, true);
});
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()
}, { loader: true })
.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 lanalyse initiale
// =====================
let btnBatch = e.target.closest('.btn-assign-batch');
if (btnBatch) {
e.preventDefault();
let row = btnBatch.closest('.epr-row');
if (!row) return;
if (btnBatch.disabled) {
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 — MSIN-4564 : sortie via Fermer en bas (garde-fou si reclic).
if (row.classList.contains('batch-mode')) {
exitBatchOrResetMode(row);
return;
}
// ON — MSIN-4530 : décoche à lentrée (séquence dabord).
// MSIN-4564 — ne plus transformer le bouton en « Annuler ».
row.classList.add('batch-mode');
container.classList.add('batch-mode');
row.querySelectorAll('.bib-start, .bib-qty, .bib-end').forEach(input => {
input.setAttribute('readonly', true);
});
row.querySelectorAll('.batch-select-range').forEach(function (cb) {
cb.checked = false;
});
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)
+ (isResetMode ? '' : bibAppendTeamModeParam('', row))
+ bibAjaxLangSuffix()
}, { loader: true })
.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-4469 — Impression : pas de réassign / reset.
if (btnReset.disabled || bibRowIsProductionLocked(row)) {
bibAlertProductionLocked();
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 — MSIN-4564 : sortie via Fermer en bas (garde-fou si reclic).
// =====================
if (row.classList.contains('reset-mode')) {
exitBatchOrResetMode(row);
return;
}
// =====================
// ON — MSIN-4526 : mode local, pas de refresh_ranges (CTE trous).
// MSIN-4564 — ne plus transformer le bouton en « Annuler ».
// =====================
row.classList.add('reset-mode');
row.dataset.mode = 'reset';
container.classList.add('batch-mode');
row.querySelectorAll('.bib-start, .bib-qty, .bib-end').forEach(input => {
input.setAttribute('readonly', true);
});
row.querySelectorAll('.batch-select-range').forEach(function (cb) {
cb.checked = false;
});
let goBtn = row.querySelector('.btn-go-batch');
if (goBtn) {
goBtn.textContent = row.dataset.resetLabel || goBtn.textContent;
}
syncBibUiState(row);
return;
}
// =====================
// MSIN-4564 — FERMER (batch / reset)
// =====================
let btnFermerAssign = e.target.closest('.btn-fermer-assign');
if (btnFermerAssign) {
e.preventDefault();
let row = btnFermerAssign.closest('.epr-row');
if (!row) return;
exitBatchOrResetMode(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()
}, { loader: true })
.then(res => res.json())
.then(data => {
if (!data.success) {
alert(data.message || bibJs('jsErrGeneric'));
return;
}
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 67 (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 (btnAuto.disabled) {
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();
}
}
})();