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