5200 lines
216 KiB
JavaScript
5200 lines
216 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();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* MSIN-4539 / MSIN-4550 — fetch ajax_bib_range.php.
|
||
* loader:true dès qu’un risque de délai (deferred / 1er paint) — voir projet/10-loader-coureur.mdc.
|
||
*/
|
||
function bibFetch(url, options, settings) {
|
||
settings = settings || {};
|
||
var useLoader = settings.loader === true;
|
||
if (useLoader) {
|
||
bibLoaderShow();
|
||
}
|
||
return fetch(url, options).finally(function () {
|
||
if (useLoader) {
|
||
bibLoaderHide();
|
||
}
|
||
});
|
||
}
|
||
|
||
var BIB_BATCH_CHUNK_SIZE = 50;
|
||
|
||
function bibBatchProgressShow(processed, total) {
|
||
var intTotal = total > 0 ? total : 1;
|
||
var msg = bibJsFmt('jsBatchProgress', processed, intTotal);
|
||
if (window.Ms1Loader && Ms1Loader.showProgress) {
|
||
Ms1Loader.showProgress(processed, intTotal, msg);
|
||
} else {
|
||
bibLoaderShow();
|
||
}
|
||
}
|
||
|
||
function bibBatchProgressHide() {
|
||
if (window.Ms1Loader && Ms1Loader.hide) {
|
||
Ms1Loader.hide();
|
||
} else {
|
||
bibLoaderHide();
|
||
}
|
||
}
|
||
|
||
/** MSIN-4436 — Force la fermeture du loader (batch global : évite overlay bloqué). */
|
||
function bibBatchProgressForceHide() {
|
||
bibLoaderDepth = 0;
|
||
bibBatchProgressHide();
|
||
}
|
||
|
||
function bibAfterBatchGoSuccess(row, data, isResetMode, options) {
|
||
options = options || {};
|
||
let existing = document.querySelector('.epr-row-view');
|
||
if (existing) {
|
||
existing.remove();
|
||
}
|
||
|
||
// MSIN-4528 — Reset : pas d'injection de grille (milliers de lignes = UI figée).
|
||
if (!isResetMode && data.html) {
|
||
row.insertAdjacentHTML('afterend', data.html);
|
||
}
|
||
|
||
if (isResetMode && data.message) {
|
||
let info = row.querySelector('.epr-actions .batch-info-text');
|
||
if (info) {
|
||
info.textContent = data.message;
|
||
}
|
||
}
|
||
|
||
// MSIN-4534 — Après GO : une seule paint (refresh lite + stats), pas de hop-hop menus.
|
||
options.skipAnomalies = true;
|
||
options.skipQtySummary = true;
|
||
options.refreshLite = true;
|
||
options.skipSync = true;
|
||
if (options.loader === undefined) {
|
||
options.loader = !isResetMode;
|
||
}
|
||
|
||
return bibAfterBatchGoRefreshOnly(row, isResetMode, options);
|
||
}
|
||
|
||
function bibAfterBatchGoRefreshOnly(row, isResetMode, options) {
|
||
options = options || {};
|
||
if (!row) {
|
||
return Promise.resolve();
|
||
}
|
||
|
||
if (isResetMode) {
|
||
row.classList.remove('reset-mode');
|
||
row.dataset.mode = '';
|
||
|
||
let btnReset = row.querySelector('.btn-reset');
|
||
if (btnReset) {
|
||
btnReset.textContent = row.dataset.resetLabel || btnReset.textContent;
|
||
}
|
||
}
|
||
row.classList.remove('batch-mode');
|
||
|
||
let container = row.querySelector('.bib-container');
|
||
if (container) {
|
||
container.classList.remove('batch-mode');
|
||
}
|
||
|
||
let btnBatch = row.querySelector('.btn-assign-batch');
|
||
if (btnBatch) {
|
||
btnBatch.textContent = row.dataset.batchLabel || btnBatch.textContent;
|
||
}
|
||
|
||
row.querySelectorAll('.bib-start, .bib-qty, .bib-end').forEach(input => {
|
||
input.removeAttribute('readonly');
|
||
});
|
||
|
||
row.querySelectorAll('.batch-select-range').forEach(cb => {
|
||
cb.checked = false;
|
||
cb.disabled = false;
|
||
});
|
||
|
||
// MSIN-4469 — Ne pas réouvrir les champs si impression verrouillée.
|
||
bibApplyRangeInputLockState(row);
|
||
|
||
// MSIN-4534 — Pas de syncBibUiState ici (stats encore stale → Réinit en retard).
|
||
var useLoader = options.loader !== false;
|
||
var skipAnomalies = options.skipAnomalies === true;
|
||
var skipQtySummary = options.skipQtySummary === true;
|
||
var refreshLite = options.refreshLite === true || isResetMode === true;
|
||
var skipSyncUntilStats = options.skipSync === true;
|
||
|
||
return bibFetch('/ajax_bib_range.php', {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||
body:
|
||
'action=refresh_ranges'
|
||
+ '&epr_id=' + encodeURIComponent(row.dataset.eprId)
|
||
+ '&mode=assign'
|
||
+ (refreshLite ? '&lite=1' : '')
|
||
+ bibAjaxLangSuffix()
|
||
}, { loader: useLoader })
|
||
.then(function (res) {
|
||
if (!res.ok) {
|
||
throw new Error(bibJs('jsErrGeneric'));
|
||
}
|
||
return res.json();
|
||
})
|
||
.then(function (refresh) {
|
||
|
||
if (!refresh.success) {
|
||
return;
|
||
}
|
||
|
||
let containerRef = setBibContainerFromAjax(row, refresh, {
|
||
skipAnomalies: skipAnomalies,
|
||
skipQtySummary: skipQtySummary,
|
||
skipSync: skipSyncUntilStats
|
||
});
|
||
if (!containerRef) {
|
||
return;
|
||
}
|
||
|
||
return bibFetch('/ajax_bib_range.php', {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/x-www-form-urlencoded'
|
||
},
|
||
body:
|
||
'action=batch_analysis'
|
||
+ '&epr_id=' + encodeURIComponent(row.dataset.eprId)
|
||
+ bibAjaxLangSuffix()
|
||
}, { loader: false })
|
||
.then(function (res) { return res.json(); })
|
||
.then(function (stats) {
|
||
|
||
if (stats && stats.success) {
|
||
bibSyncEprBibStats(row, stats.info);
|
||
}
|
||
syncBibUiState(row);
|
||
});
|
||
});
|
||
}
|
||
|
||
function bibBatchSortMaxLevels() {
|
||
return 4;
|
||
}
|
||
|
||
function bibGetSortKeysFromRoot(root, classPrefix) {
|
||
var max = bibBatchSortMaxLevels();
|
||
var sorts = [];
|
||
var i;
|
||
var sel;
|
||
if (!root) {
|
||
for (i = 0; i < max; i++) {
|
||
sorts.push('');
|
||
}
|
||
return {
|
||
sorts: sorts,
|
||
sort1: '',
|
||
sort2: ''
|
||
};
|
||
}
|
||
for (i = 1; i <= max; i++) {
|
||
sel = root.querySelector('select[data-sort-level="' + i + '"]');
|
||
if (!sel && classPrefix) {
|
||
sel = root.querySelector(
|
||
i === 1
|
||
? 'select.' + classPrefix
|
||
: 'select.' + classPrefix + '-' + i
|
||
);
|
||
}
|
||
sorts.push(sel ? String(sel.value || '').trim() : '');
|
||
}
|
||
return {
|
||
sorts: sorts,
|
||
sort1: sorts[0] || '',
|
||
sort2: sorts[1] || ''
|
||
};
|
||
}
|
||
|
||
function bibGetRowSortKeys(row) {
|
||
return bibGetSortKeysFromRoot(row, 'batch-order');
|
||
}
|
||
|
||
function bibGetGlobalBatchSortKeys(panel) {
|
||
var keys = bibGetSortKeysFromRoot(panel, 'bib-global-batch-order');
|
||
if (!(keys.sort1 || '')) {
|
||
keys = bibGetSortKeysFromRoot(panel, 'bib-global-gen-batch-order');
|
||
}
|
||
return keys;
|
||
}
|
||
|
||
function bibAppendBatchSortParams(body, sortKeys) {
|
||
sortKeys = sortKeys || {};
|
||
var sorts = Array.isArray(sortKeys.sorts) ? sortKeys.sorts : null;
|
||
var max = bibBatchSortMaxLevels();
|
||
var i;
|
||
var out = body || '';
|
||
if (!sorts) {
|
||
sorts = [];
|
||
for (i = 1; i <= max; i++) {
|
||
sorts.push(sortKeys['sort' + i] || '');
|
||
}
|
||
}
|
||
for (i = 0; i < max; i++) {
|
||
out += '&sort_' + (i + 1) + '=' + encodeURIComponent(sorts[i] || '');
|
||
}
|
||
return out;
|
||
}
|
||
|
||
// MSIN-4379 — Mode équipe coché à l'écran (à envoyer avec Simuler / GO).
|
||
function bibGetRowTeamMode(row) {
|
||
if (!row) {
|
||
return '';
|
||
}
|
||
var checked = row.querySelector('.team-mode-box input[type="radio"]:checked');
|
||
return checked ? String(checked.value || '').trim() : '';
|
||
}
|
||
|
||
function bibAppendTeamModeParam(body, row) {
|
||
var teamMode = bibGetRowTeamMode(row);
|
||
if (!teamMode) {
|
||
return body || '';
|
||
}
|
||
return (body || '') + '&team_mode=' + encodeURIComponent(teamMode);
|
||
}
|
||
|
||
function bibFetchBatchApplyChunk(row, selected, sortKeys, opts) {
|
||
opts = opts || {};
|
||
sortKeys = sortKeys || bibGetRowSortKeys(row);
|
||
var body =
|
||
'action=batch_apply_chunk'
|
||
+ '&epr_id=' + encodeURIComponent(row.dataset.eprId)
|
||
+ '&ranges=' + encodeURIComponent(JSON.stringify(selected))
|
||
+ bibAppendBatchSortParams('', sortKeys)
|
||
+ bibAppendTeamModeParam('', row)
|
||
+ '&chunk_size=' + BIB_BATCH_CHUNK_SIZE
|
||
+ '&total_initial=' + (opts.totalInitial || 0)
|
||
+ '&batch_reset=' + (opts.batchReset ? 1 : 0)
|
||
+ bibAjaxLangSuffix();
|
||
|
||
return fetch('/ajax_bib_range.php', {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||
body: body
|
||
})
|
||
.then(function (res) {
|
||
if (!res.ok) {
|
||
throw new Error(bibJs('jsErrGeneric'));
|
||
}
|
||
return res.json();
|
||
})
|
||
.catch(function (err) {
|
||
if (err && err.message) {
|
||
throw err;
|
||
}
|
||
throw new Error(bibJs('jsErrGeneric'));
|
||
});
|
||
}
|
||
|
||
function bibRunBatchApplyChunks(row, selected, sortKeys, options) {
|
||
options = options || {};
|
||
var showResult = options.showResult !== false;
|
||
var manageLoader = options.manageLoader !== false;
|
||
var deferUiRefresh = options.deferUiRefresh === true;
|
||
var onProgress = options.onProgress;
|
||
var totalInitial = options.totalInitial > 0
|
||
? options.totalInitial
|
||
: bibRowPendingBibs(row);
|
||
var batchReset = true;
|
||
var chunkGuard = 0;
|
||
var maxChunks = Math.max(50, Math.ceil((totalInitial || 1) / BIB_BATCH_CHUNK_SIZE) + 5);
|
||
|
||
if (manageLoader) {
|
||
bibBatchProgressShow(0, totalInitial > 0 ? totalInitial : 1);
|
||
}
|
||
|
||
function runChunk() {
|
||
chunkGuard++;
|
||
if (chunkGuard > maxChunks) {
|
||
return Promise.reject(new Error(bibJs('jsErrGeneric')));
|
||
}
|
||
|
||
return bibFetchBatchApplyChunk(row, selected, sortKeys, {
|
||
batchReset: batchReset,
|
||
totalInitial: totalInitial
|
||
}).then(function (data) {
|
||
if (!data || !data.success) {
|
||
throw new Error((data && data.message) || bibJs('jsErrGeneric'));
|
||
}
|
||
|
||
if (data.total_initial) {
|
||
totalInitial = data.total_initial;
|
||
}
|
||
batchReset = false;
|
||
|
||
var processed = data.processed || 0;
|
||
if (onProgress) {
|
||
onProgress(processed, totalInitial);
|
||
} else if (manageLoader) {
|
||
bibBatchProgressShow(processed, totalInitial);
|
||
}
|
||
|
||
if (data.complete) {
|
||
if (showResult) {
|
||
// MSIN-4534 — Attendre refresh+stats avant de baisser le loader (pas de hop-hop menus).
|
||
return bibAfterBatchGoSuccess(row, data, false, { loader: false })
|
||
.then(function () { return data; });
|
||
}
|
||
if (!deferUiRefresh) {
|
||
return bibAfterBatchGoRefreshOnly(row, false, {
|
||
loader: false,
|
||
skipAnomalies: true,
|
||
skipQtySummary: true,
|
||
refreshLite: true,
|
||
skipSync: true
|
||
}).then(function () { return data; });
|
||
}
|
||
return data;
|
||
}
|
||
|
||
return runChunk();
|
||
});
|
||
}
|
||
|
||
return runChunk()
|
||
.catch(function (err) {
|
||
if (manageLoader) {
|
||
alert(err.message || bibJs('jsErrGeneric'));
|
||
}
|
||
throw err;
|
||
})
|
||
.finally(function () {
|
||
if (manageLoader) {
|
||
bibBatchProgressHide();
|
||
}
|
||
});
|
||
}
|
||
|
||
// MSIN-4436 — Batch global (épreuves solo), chargement différé à l'ouverture.
|
||
|
||
function bibGetGlobalBatchPanel() {
|
||
return document.getElementById('bib-global-batch');
|
||
}
|
||
|
||
/** Corps du panneau (dans #bib-tool-detail-body une fois l'outil ouvert). */
|
||
function bibGetGlobalBatchBody() {
|
||
var detailBody = document.getElementById('bib-tool-detail-body');
|
||
if (detailBody) {
|
||
var inDetail = detailBody.querySelector('.bib-global-batch__body');
|
||
if (inDetail) {
|
||
return inDetail;
|
||
}
|
||
}
|
||
|
||
var panel = bibGetGlobalBatchPanel();
|
||
return panel ? panel.querySelector('.bib-global-batch__body') : null;
|
||
}
|
||
|
||
function bibGetGlobalBatchExistingSection() {
|
||
var body = bibGetGlobalBatchBody();
|
||
return body ? body.querySelector('.bib-global-batch--existing') : null;
|
||
}
|
||
|
||
function bibGetGlobalBatchGeneratedSection() {
|
||
var body = bibGetGlobalBatchBody();
|
||
return body ? body.querySelector('.bib-global-batch--generated') : null;
|
||
}
|
||
|
||
function bibInvalidateGlobalBatchPanel() {
|
||
var mount = document.getElementById('bib-global-batch-mount');
|
||
var panel = bibGetGlobalBatchPanel();
|
||
|
||
if (panel) {
|
||
panel.removeAttribute('data-global-batch-loaded');
|
||
panel.setAttribute('data-global-batch-deferred', '1');
|
||
}
|
||
|
||
if (mount && panel) {
|
||
mount.innerHTML = ''
|
||
+ '<div id="bib-global-batch"'
|
||
+ ' class="bib-global-batch bib-tool-panel"'
|
||
+ ' data-bib-tool="global_batch"'
|
||
+ ' data-global-batch-deferred="1">'
|
||
+ '<div class="bib-global-batch__body bib-ui-hidden"></div>'
|
||
+ '</div>';
|
||
}
|
||
}
|
||
|
||
function bibEscHtml(str) {
|
||
return String(str == null ? '' : str)
|
||
.replace(/&/g, '&')
|
||
.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;
|
||
bibSyncWorkspaceTabHighlight();
|
||
bibSyncWorkspaceSurfaceVisibility();
|
||
|
||
// MSIN-4546 — Charger Production seulement quand on ouvre cet espace.
|
||
if (workspaceId === 'production') {
|
||
bibEnsureProductionPanelLoaded().then(function () {
|
||
initBibProductionFieldsChooser(moduleBib);
|
||
});
|
||
}
|
||
|
||
// MSIN-4475 — Modes d'assignation : afficher les choix tout de suite (sans clic tuile).
|
||
if (workspaceId === 'operations' && options.keepTool !== true) {
|
||
var autoTool = panel.getAttribute('data-bib-auto-tool');
|
||
if (autoTool) {
|
||
bibOpenTool(autoTool);
|
||
}
|
||
}
|
||
}
|
||
|
||
var bibProductionLoadPromise = null;
|
||
|
||
/**
|
||
* MSIN-4546 — Onglet Production = page séparée : AJAX au 1er clic seulement.
|
||
*/
|
||
function bibEnsureProductionPanelLoaded() {
|
||
var panel = moduleBib.querySelector('[data-bib-workspace-panel="production"]');
|
||
var mount = document.getElementById('bib-production-mount');
|
||
if (!panel) {
|
||
return Promise.resolve();
|
||
}
|
||
// Déjà chargé (HTML production en place) → juste s’assurer que le chooser est vivant.
|
||
if (panel.getAttribute('data-production-loaded') === '1' || !mount) {
|
||
initBibProductionFieldsChooser(panel);
|
||
return Promise.resolve(panel);
|
||
}
|
||
if (panel.getAttribute('data-production-deferred') !== '1'
|
||
&& mount.getAttribute('data-production-deferred') !== '1') {
|
||
initBibProductionFieldsChooser(panel);
|
||
return Promise.resolve(panel);
|
||
}
|
||
if (bibProductionLoadPromise) {
|
||
return bibProductionLoadPromise;
|
||
}
|
||
|
||
bibProductionLoadPromise = bibFetch('/ajax_bib_range.php', {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||
body: 'action=production_panel'
|
||
+ '&eve_id=' + encodeURIComponent(moduleBib.dataset.eveId || '')
|
||
+ bibAjaxLangSuffix()
|
||
}, { loader: true })
|
||
.then(function (res) { return res.json(); })
|
||
.then(function (data) {
|
||
if (!data || !data.success || !data.html) {
|
||
throw new Error((data && data.message) || bibJs('jsErrGeneric') || 'Erreur');
|
||
}
|
||
// Garder #bib-production-mount (innerHTML) pour ne pas perdre la cible d’erreur.
|
||
var liveMount = document.getElementById('bib-production-mount');
|
||
if (liveMount) {
|
||
liveMount.innerHTML = data.html;
|
||
liveMount.removeAttribute('data-production-deferred');
|
||
} else {
|
||
panel.innerHTML = data.html;
|
||
}
|
||
panel.removeAttribute('data-production-deferred');
|
||
panel.setAttribute('data-production-loaded', '1');
|
||
initModuleBibTippy(panel);
|
||
initBibProductionFieldsChooser(panel);
|
||
return panel;
|
||
})
|
||
.catch(function (err) {
|
||
var msg = (err && err.message) ? err.message : (bibJs('jsServerError') || 'Erreur serveur');
|
||
var errHost = document.getElementById('bib-production-mount') || panel;
|
||
if (errHost) {
|
||
errHost.innerHTML = '<div class="text-danger small" style="padding:12px;">'
|
||
+ bibTippyEscapeHtml(msg)
|
||
+ '</div>';
|
||
}
|
||
})
|
||
.finally(function () {
|
||
bibProductionLoadPromise = null;
|
||
});
|
||
|
||
return bibProductionLoadPromise;
|
||
}
|
||
|
||
/** MSIN-4512 — PDF ouvert : ne pas laisser l’onglet workspace allumé en parallèle. */
|
||
function bibSyncWorkspaceTabHighlight() {
|
||
var highlightWorkspace = (bibActiveTool === 'dist_print') ? null : bibActiveWorkspace;
|
||
moduleBib.querySelectorAll('.bib-workspace-tab').forEach(function (tab) {
|
||
var active = !!highlightWorkspace
|
||
&& tab.getAttribute('data-bib-workspace') === highlightWorkspace;
|
||
tab.classList.toggle('is-active', active);
|
||
tab.setAttribute('aria-selected', active ? 'true' : 'false');
|
||
});
|
||
}
|
||
|
||
/**
|
||
* MSIN-4512 — Une surface à la fois.
|
||
* PDF distribution : masquer espaces + épreuves (sinon l’assignation reste sous le PDF).
|
||
* Autres cas : panneau de l’espace actif + épreuves seulement en préparation.
|
||
*/
|
||
function bibSyncWorkspaceSurfaceVisibility() {
|
||
var blnPdfExclusive = (bibActiveTool === 'dist_print');
|
||
moduleBib.querySelectorAll('[data-bib-workspace-panel]').forEach(function (workspacePanel) {
|
||
var show = !blnPdfExclusive
|
||
&& workspacePanel.getAttribute('data-bib-workspace-panel') === bibActiveWorkspace;
|
||
workspacePanel.classList.toggle('bib-ui-hidden', !show);
|
||
});
|
||
|
||
var races = document.getElementById('bib-preparation-races');
|
||
if (races) {
|
||
races.classList.toggle(
|
||
'bib-ui-hidden',
|
||
blnPdfExclusive || bibActiveWorkspace !== 'preparation'
|
||
);
|
||
}
|
||
}
|
||
|
||
function bibWorkspaceForTool(toolId) {
|
||
if (toolId === 'event_config') {
|
||
return 'settings';
|
||
}
|
||
if (toolId === 'global_batch') {
|
||
return 'operations';
|
||
}
|
||
// MSIN-4470 / MSIN-4512 — PDF reste une action globale (mémorise l’espace courant
|
||
// pour y revenir à la fermeture) mais la surface sous-jacente est masquée.
|
||
if (toolId === 'dist_print') {
|
||
return bibActiveWorkspace;
|
||
}
|
||
return 'preparation';
|
||
}
|
||
|
||
function bibGetToolPanel(toolId) {
|
||
return document.querySelector('#bib-tool-store [data-bib-tool="' + toolId + '"]');
|
||
}
|
||
|
||
function bibGetToolContentNode(panel, toolId) {
|
||
if (!panel) {
|
||
return null;
|
||
}
|
||
if (toolId === 'global_batch') {
|
||
return panel.querySelector('.bib-global-batch__body');
|
||
}
|
||
return panel.querySelector('.epr-content');
|
||
}
|
||
|
||
function bibInvalidateToolSlot(toolId) {
|
||
if (bibToolContentSlots[toolId]) {
|
||
delete bibToolContentSlots[toolId];
|
||
}
|
||
}
|
||
|
||
function bibRestoreToolContent(toolId) {
|
||
var slot = bibToolContentSlots[toolId];
|
||
if (!slot || !slot.content || !slot.placeholder || !slot.placeholder.parentNode) {
|
||
return;
|
||
}
|
||
|
||
slot.placeholder.parentNode.insertBefore(slot.content, slot.placeholder.nextSibling);
|
||
if (toolId === 'global_batch') {
|
||
slot.content.classList.add('bib-ui-hidden');
|
||
}
|
||
}
|
||
|
||
function bibMountToolContent(toolId) {
|
||
var panel = bibGetToolPanel(toolId);
|
||
var detailBody = document.getElementById('bib-tool-detail-body');
|
||
var content = bibGetToolContentNode(panel, toolId);
|
||
|
||
if (!panel || !detailBody || !content) {
|
||
return false;
|
||
}
|
||
|
||
if (!bibToolContentSlots[toolId]) {
|
||
var placeholder = document.createComment('bib-tool-slot-' + toolId);
|
||
content.parentNode.insertBefore(placeholder, content);
|
||
bibToolContentSlots[toolId] = {
|
||
content: content,
|
||
placeholder: placeholder,
|
||
panel: panel
|
||
};
|
||
}
|
||
|
||
detailBody.appendChild(content);
|
||
if (toolId === 'global_batch') {
|
||
content.classList.remove('bib-ui-hidden');
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
function bibSetActiveToolButton(toolId) {
|
||
moduleBib.querySelectorAll('.bib-tool-btn').forEach(function (btn) {
|
||
var active = !!toolId && btn.getAttribute('data-bib-tool') === toolId;
|
||
btn.classList.toggle('is-active', active);
|
||
btn.setAttribute('aria-expanded', active ? 'true' : 'false');
|
||
});
|
||
}
|
||
|
||
function bibSetToolDetailTitle(toolId) {
|
||
var titleEl = document.getElementById('bib-tool-detail-title');
|
||
if (!titleEl) {
|
||
return;
|
||
}
|
||
|
||
if (!toolId) {
|
||
titleEl.textContent = '';
|
||
return;
|
||
}
|
||
|
||
var btn = moduleBib.querySelector('.bib-tool-btn[data-bib-tool="' + toolId + '"]');
|
||
if (btn) {
|
||
titleEl.textContent = btn.getAttribute('data-bib-tool-label') || '';
|
||
return;
|
||
}
|
||
|
||
// MSIN-4475 — Titre depuis le panneau (outil ouvert auto, sans tuile).
|
||
var autoPanel = moduleBib.querySelector(
|
||
'[data-bib-workspace-panel][data-bib-auto-tool="' + toolId + '"]'
|
||
);
|
||
titleEl.textContent = autoPanel
|
||
? (autoPanel.getAttribute('data-bib-auto-tool-label') || '')
|
||
: '';
|
||
}
|
||
|
||
// MSIN-4470 — Le panneau PDF s'ouvre immédiatement sous la barre supérieure.
|
||
function bibPositionToolDetail(toolId) {
|
||
var detail = document.getElementById('bib-tool-detail');
|
||
var defaultSlot = document.getElementById('bib-tool-detail-default-slot');
|
||
if (!detail || !defaultSlot || !defaultSlot.parentNode) {
|
||
return;
|
||
}
|
||
|
||
if (toolId === 'dist_print') {
|
||
var firstWorkspacePanel = moduleBib.querySelector('[data-bib-workspace-panel]');
|
||
if (firstWorkspacePanel && firstWorkspacePanel.parentNode) {
|
||
firstWorkspacePanel.parentNode.insertBefore(detail, firstWorkspacePanel);
|
||
}
|
||
return;
|
||
}
|
||
|
||
defaultSlot.parentNode.insertBefore(detail, defaultSlot.nextSibling);
|
||
}
|
||
|
||
function bibCloseTool(options) {
|
||
options = options || {};
|
||
if (!bibActiveTool) {
|
||
return;
|
||
}
|
||
|
||
var closedTool = bibActiveTool;
|
||
bibRestoreToolContent(bibActiveTool);
|
||
bibInvalidateToolSlot(bibActiveTool);
|
||
bibActiveTool = null;
|
||
bibSetActiveToolButton(null);
|
||
bibSetToolDetailTitle(null);
|
||
bibSyncWorkspaceTabHighlight();
|
||
bibSyncWorkspaceSurfaceVisibility();
|
||
bibRemoveGlobalSimViews();
|
||
|
||
var detail = document.getElementById('bib-tool-detail');
|
||
var detailBody = document.getElementById('bib-tool-detail-body');
|
||
if (detailBody) {
|
||
detailBody.innerHTML = '';
|
||
}
|
||
if (detail) {
|
||
detail.classList.add('bib-ui-hidden');
|
||
}
|
||
bibPositionToolDetail(null);
|
||
|
||
// MSIN-4475 — Fermer les modes (plus de tuile) ramène à la préparation.
|
||
if (options.returnToPreparation === true
|
||
&& closedTool === 'global_batch'
|
||
&& bibActiveWorkspace === 'operations') {
|
||
bibSetWorkspace('preparation', { keepTool: true });
|
||
}
|
||
}
|
||
|
||
function bibSyncToolNavBadges(toolId) {
|
||
var panel = bibGetToolPanel(toolId);
|
||
var btn = moduleBib.querySelector('.bib-tool-btn[data-bib-tool="' + toolId + '"]');
|
||
if (!panel || !btn) {
|
||
return;
|
||
}
|
||
|
||
var dest = btn.querySelector('.bib-tool-btn__badges');
|
||
if (!dest) {
|
||
return;
|
||
}
|
||
|
||
if (toolId === 'event_config') {
|
||
var srcNote = panel.querySelector('[data-bib-inter-epr-note]');
|
||
var destNote = dest.querySelector('[data-bib-inter-epr-note]');
|
||
if (srcNote && destNote) {
|
||
destNote.className = srcNote.className;
|
||
}
|
||
return;
|
||
}
|
||
|
||
if (toolId === 'qty_summary') {
|
||
dest.innerHTML = '';
|
||
return;
|
||
}
|
||
|
||
if (toolId === 'anomalies') {
|
||
var anomCount = panel.querySelector('.bib-anomalies-count');
|
||
var destBadge = dest.querySelector('[data-bib-anomalies-nav-badge]');
|
||
var strTodoFmt = bibJs('jsAnomaliesNavTodoFmt') || 'Élément à valider : %d';
|
||
var intCount = 0;
|
||
var blnPending = true;
|
||
|
||
if (anomCount) {
|
||
blnPending = anomCount.getAttribute('aria-busy') === 'true';
|
||
if (!blnPending) {
|
||
intCount = parseInt(String(anomCount.textContent || '').trim(), 10);
|
||
if (isNaN(intCount)) {
|
||
intCount = 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
function bibAnomaliesNavBadgeLabel(count) {
|
||
return strTodoFmt.replace(/%d/g, String(count));
|
||
}
|
||
|
||
if (!destBadge) {
|
||
dest.innerHTML = '';
|
||
if (!blnPending && intCount > 0) {
|
||
var strLabel = bibAnomaliesNavBadgeLabel(intCount);
|
||
dest.innerHTML = '<span class="epr-header-summary bib-event-config-note bib-anomalies-nav-badge"'
|
||
+ ' data-bib-anomalies-nav-badge="1"'
|
||
+ ' data-bib-anomalies-nav-count="' + intCount + '"'
|
||
+ ' title="' + strLabel.replace(/"/g, '"') + '">'
|
||
+ strLabel
|
||
+ '</span>';
|
||
}
|
||
return;
|
||
}
|
||
|
||
if (blnPending || intCount <= 0) {
|
||
destBadge.classList.add('bib-ui-hidden');
|
||
destBadge.setAttribute('aria-hidden', 'true');
|
||
destBadge.textContent = '';
|
||
destBadge.removeAttribute('data-bib-anomalies-nav-count');
|
||
} else {
|
||
var strBadgeLabel = bibAnomaliesNavBadgeLabel(intCount);
|
||
destBadge.classList.remove('bib-ui-hidden');
|
||
destBadge.removeAttribute('aria-hidden');
|
||
destBadge.textContent = strBadgeLabel;
|
||
destBadge.setAttribute('title', strBadgeLabel);
|
||
destBadge.setAttribute('data-bib-anomalies-nav-count', String(intCount));
|
||
}
|
||
}
|
||
}
|
||
|
||
function bibSyncAllToolNavBadges() {
|
||
bibSyncToolNavBadges('event_config');
|
||
bibSyncToolNavBadges('anomalies');
|
||
}
|
||
|
||
function bibEnsureToolLoaded(toolId) {
|
||
if (toolId === 'qty_summary') {
|
||
var qtyPanel = bibGetToolPanel('qty_summary');
|
||
if (qtyPanel && qtyPanel.getAttribute('data-bib-qty-summary-deferred') === '1') {
|
||
return refreshBibQtySummaryPanel();
|
||
}
|
||
}
|
||
|
||
if (toolId === 'dist_print') {
|
||
var printPanel = bibGetToolPanel('dist_print');
|
||
if (printPanel && printPanel.getAttribute('data-bib-dist-print-deferred') === '1') {
|
||
return refreshBibDistPrintPanel();
|
||
}
|
||
}
|
||
|
||
if (toolId === 'global_batch') {
|
||
var batchPanel = bibGetToolPanel('global_batch');
|
||
if (batchPanel && batchPanel.getAttribute('data-global-batch-deferred') === '1') {
|
||
return bibEnsureGlobalBatchPanelLoaded();
|
||
}
|
||
}
|
||
|
||
return Promise.resolve();
|
||
}
|
||
|
||
function bibOpenTool(toolId) {
|
||
if (!toolId) {
|
||
return Promise.resolve();
|
||
}
|
||
|
||
var workspaceId = bibWorkspaceForTool(toolId);
|
||
if (bibActiveWorkspace !== workspaceId) {
|
||
bibSetWorkspace(workspaceId, { keepTool: true });
|
||
}
|
||
|
||
if (bibActiveTool === toolId) {
|
||
bibCloseTool();
|
||
return Promise.resolve();
|
||
}
|
||
|
||
var prevTool = bibActiveTool;
|
||
if (prevTool) {
|
||
bibRestoreToolContent(prevTool);
|
||
bibInvalidateToolSlot(prevTool);
|
||
}
|
||
bibRemoveGlobalSimViews();
|
||
|
||
// MSIN-4550 — coureur dès le clic si chargement deferred possible (avant le fetch).
|
||
var panelPre = bibGetToolPanel(toolId);
|
||
var blnDeferredLoad = false;
|
||
if (toolId === 'dist_print' && panelPre
|
||
&& panelPre.getAttribute('data-bib-dist-print-deferred') === '1') {
|
||
blnDeferredLoad = true;
|
||
} else if (toolId === 'qty_summary' && panelPre
|
||
&& panelPre.getAttribute('data-bib-qty-summary-deferred') === '1') {
|
||
blnDeferredLoad = true;
|
||
} else if (toolId === 'global_batch' && panelPre
|
||
&& panelPre.getAttribute('data-global-batch-deferred') === '1') {
|
||
blnDeferredLoad = true;
|
||
}
|
||
if (blnDeferredLoad) {
|
||
bibLoaderShow();
|
||
}
|
||
|
||
return bibEnsureToolLoaded(toolId).then(function () {
|
||
var panel = bibGetToolPanel(toolId);
|
||
if (!panel || !bibMountToolContent(toolId)) {
|
||
return;
|
||
}
|
||
|
||
bibActiveTool = toolId;
|
||
bibSetActiveToolButton(toolId);
|
||
bibSetToolDetailTitle(toolId);
|
||
bibPositionToolDetail(toolId);
|
||
bibSyncWorkspaceTabHighlight();
|
||
bibSyncWorkspaceSurfaceVisibility();
|
||
|
||
var detail = document.getElementById('bib-tool-detail');
|
||
if (detail) {
|
||
detail.classList.remove('bib-ui-hidden');
|
||
detail.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
||
}
|
||
|
||
if (toolId === 'global_batch') {
|
||
/* Sections repliées à l'arrivée — analyse au déploiement d'une section. */
|
||
}
|
||
|
||
bibSyncToolNavBadges(toolId);
|
||
initModuleBibTippy(document.getElementById('bib-tool-detail'));
|
||
}).finally(function () {
|
||
if (blnDeferredLoad) {
|
||
bibLoaderHide();
|
||
}
|
||
});
|
||
}
|
||
|
||
function bibRemountActiveToolAfterRefresh(toolId) {
|
||
if (bibActiveTool !== toolId) {
|
||
return;
|
||
}
|
||
|
||
bibInvalidateToolSlot(toolId);
|
||
bibMountToolContent(toolId);
|
||
initModuleBibTippy(document.getElementById('bib-tool-detail'));
|
||
|
||
if (toolId === 'global_batch') {
|
||
/* Sections repliées à l'arrivée — analyse au déploiement d'une section. */
|
||
}
|
||
}
|
||
|
||
var bibGlobalBatchLoadPromise = null;
|
||
|
||
function bibEnsureGlobalBatchPanelLoaded() {
|
||
var mount = document.getElementById('bib-global-batch-mount');
|
||
var panel = bibGetGlobalBatchPanel();
|
||
|
||
if (!mount || !panel) {
|
||
return Promise.resolve(null);
|
||
}
|
||
|
||
if (panel.getAttribute('data-global-batch-loaded') === '1') {
|
||
return Promise.resolve(panel);
|
||
}
|
||
|
||
if (bibGlobalBatchLoadPromise) {
|
||
return bibGlobalBatchLoadPromise;
|
||
}
|
||
|
||
bibGlobalBatchLoadPromise = bibFetch('/ajax_bib_range.php', {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||
body:
|
||
'action=global_batch_panel'
|
||
+ '&eve_id=' + encodeURIComponent(moduleBib.dataset.eveId || '')
|
||
+ bibAjaxLangSuffix()
|
||
}, { loader: true })
|
||
.then(function (res) { return res.json(); })
|
||
.then(function (data) {
|
||
if (!data.success || !data.html) {
|
||
throw new Error(data.message || bibJs('jsErrGeneric'));
|
||
}
|
||
|
||
mount.innerHTML = data.html;
|
||
panel = bibGetGlobalBatchPanel();
|
||
if (panel) {
|
||
panel.setAttribute('data-global-batch-loaded', '1');
|
||
panel.removeAttribute('data-global-batch-deferred');
|
||
}
|
||
initModuleBibTippy(mount);
|
||
bibRemountActiveToolAfterRefresh('global_batch');
|
||
var genSectionLoaded = bibGetGlobalBatchGeneratedSection();
|
||
if (genSectionLoaded) {
|
||
bibBindGlobalGeneratedRange(genSectionLoaded);
|
||
}
|
||
return panel;
|
||
})
|
||
.finally(function () {
|
||
bibGlobalBatchLoadPromise = null;
|
||
});
|
||
|
||
return bibGlobalBatchLoadPromise;
|
||
}
|
||
|
||
function bibGlobalBatchSetToggleState(toggle, isOpen) {
|
||
if (!toggle) {
|
||
return;
|
||
}
|
||
toggle.setAttribute('aria-expanded', isOpen ? 'true' : 'false');
|
||
var label = isOpen
|
||
? (toggle.getAttribute('data-label-close') || '')
|
||
: (toggle.getAttribute('data-label-open') || '');
|
||
if (label) {
|
||
toggle.textContent = label;
|
||
}
|
||
}
|
||
|
||
function bibGlobalBatchOpenPanel(panel) {
|
||
if (!panel) {
|
||
return;
|
||
}
|
||
var body = panel.querySelector('.bib-global-batch__body');
|
||
var toggle = panel.querySelector('.bib-global-batch-toggle');
|
||
if (body) {
|
||
body.classList.remove('bib-ui-hidden');
|
||
}
|
||
bibGlobalBatchSetToggleState(toggle, true);
|
||
}
|
||
|
||
function bibSetGlobalBatchInfo(infoEl, text, state) {
|
||
if (!infoEl) {
|
||
return;
|
||
}
|
||
|
||
infoEl.textContent = text || '';
|
||
infoEl.classList.remove('text-muted', 'text-danger', 'text-warning', 'text-success');
|
||
|
||
if (state === 'error') {
|
||
infoEl.classList.add('text-danger');
|
||
} else if (state === 'warning') {
|
||
infoEl.classList.add('text-warning');
|
||
} else if (state === 'ok') {
|
||
infoEl.classList.add('text-success');
|
||
} else {
|
||
infoEl.classList.add('text-muted');
|
||
}
|
||
}
|
||
|
||
function bibCollectGlobalBatchPlans() {
|
||
var section = bibGetGlobalBatchExistingSection();
|
||
if (!section) {
|
||
return [];
|
||
}
|
||
|
||
var plans = [];
|
||
section.querySelectorAll('.bib-global-epr').forEach(function (eprBlock) {
|
||
var eprCb = eprBlock.querySelector('.bib-global-epr-select');
|
||
if (!eprCb || !eprCb.checked) {
|
||
return;
|
||
}
|
||
|
||
var eprId = parseInt(eprCb.dataset.eprId || eprBlock.dataset.eprId || '0', 10);
|
||
if (!eprId) {
|
||
return;
|
||
}
|
||
|
||
var ranges = [];
|
||
eprBlock.querySelectorAll('.bib-global-range-select:checked').forEach(function (rangeCb) {
|
||
ranges.push(rangeCb.dataset.rangeId);
|
||
});
|
||
|
||
if (ranges.length > 0) {
|
||
plans.push({ epr_id: eprId, ranges: ranges });
|
||
}
|
||
});
|
||
|
||
return plans;
|
||
}
|
||
|
||
function updateGlobalBatchAnalysis() {
|
||
var section = bibGetGlobalBatchExistingSection();
|
||
if (!section || !section.querySelector('.bib-global-epr-select')) {
|
||
return Promise.resolve();
|
||
}
|
||
|
||
var plans = bibCollectGlobalBatchPlans();
|
||
var infoEl = section.querySelector('.bib-global-batch__info');
|
||
var sortKeys = bibGetGlobalBatchSortKeys(section);
|
||
|
||
if (!infoEl) {
|
||
return Promise.resolve();
|
||
}
|
||
|
||
if (plans.length === 0) {
|
||
bibSetGlobalBatchInfo(
|
||
infoEl,
|
||
bibJs('jsGlobalNoEpr') || bibJs('jsBatchNone'),
|
||
'error'
|
||
);
|
||
return Promise.resolve(null);
|
||
}
|
||
|
||
var hasRange = plans.some(function (p) { return p.ranges.length > 0; });
|
||
if (!hasRange) {
|
||
bibSetGlobalBatchInfo(
|
||
infoEl,
|
||
bibJs('jsGlobalNoSeq') || bibJs('jsNoSeqSelected'),
|
||
'error'
|
||
);
|
||
return Promise.resolve(null);
|
||
}
|
||
|
||
bibSetGlobalBatchInfo(infoEl, bibJs('jsLoaderWait') || '…', 'normal');
|
||
|
||
return fetch('/ajax_bib_range.php', {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||
body:
|
||
'action=batch_global_analysis'
|
||
+ '&eve_id=' + encodeURIComponent(moduleBib.dataset.eveId || '')
|
||
+ bibAppendBatchSortParams('', sortKeys)
|
||
+ '&plans=' + encodeURIComponent(JSON.stringify(plans))
|
||
+ bibAjaxLangSuffix()
|
||
})
|
||
.then(function (res) { return res.json(); })
|
||
.then(function (data) {
|
||
if (!data.success) {
|
||
bibSetGlobalBatchInfo(
|
||
infoEl,
|
||
data.message || bibJs('jsErrGeneric'),
|
||
'error'
|
||
);
|
||
return data;
|
||
}
|
||
|
||
var state = (data.stats && data.stats.nb_manque > 0) ? 'warning' : 'normal';
|
||
bibSetGlobalBatchInfo(infoEl, data.info || '', state);
|
||
return data;
|
||
})
|
||
.catch(function () {
|
||
bibSetGlobalBatchInfo(infoEl, bibJs('jsErrGeneric'), 'error');
|
||
return null;
|
||
});
|
||
}
|
||
|
||
function bibCollectGlobalBatchGeneratedEprIds() {
|
||
var section = bibGetGlobalBatchGeneratedSection();
|
||
if (!section) {
|
||
return [];
|
||
}
|
||
|
||
var ids = [];
|
||
section.querySelectorAll('.bib-global-gen-epr-select:checked').forEach(function (cb) {
|
||
var eprId = parseInt(cb.dataset.eprId || '0', 10);
|
||
if (eprId) {
|
||
ids.push(eprId);
|
||
}
|
||
});
|
||
|
||
return ids;
|
||
}
|
||
|
||
function bibCollectGlobalBatchGeneratedPending() {
|
||
var section = bibGetGlobalBatchGeneratedSection();
|
||
if (!section) {
|
||
return 0;
|
||
}
|
||
|
||
var total = 0;
|
||
section.querySelectorAll('.bib-global-gen-epr-select:checked').forEach(function (cb) {
|
||
var block = cb.closest('.bib-global-epr');
|
||
var pending = block
|
||
? parseInt(block.dataset.pending || '0', 10)
|
||
: 0;
|
||
if (pending > 0) {
|
||
total += pending;
|
||
}
|
||
});
|
||
|
||
return total;
|
||
}
|
||
|
||
function bibGetGlobalBatchGeneratedRangeFields(section) {
|
||
section = section || bibGetGlobalBatchGeneratedSection();
|
||
if (!section) {
|
||
return null;
|
||
}
|
||
|
||
var wrap = section.querySelector('.bib-global-gen-range');
|
||
if (!wrap) {
|
||
return null;
|
||
}
|
||
|
||
return {
|
||
wrap: wrap,
|
||
start: wrap.querySelector('.bib-global-gen-start'),
|
||
qty: wrap.querySelector('.bib-global-gen-qty'),
|
||
end: wrap.querySelector('.bib-global-gen-end'),
|
||
feedback: wrap.querySelector('.bib-global-gen-range__feedback'),
|
||
qtyEl: wrap.querySelector('.bib-global-gen-range__qty'),
|
||
dupesEl: wrap.querySelector('.bib-global-gen-range__dupes'),
|
||
autoEl: wrap.querySelector('.bib-global-gen-range__auto')
|
||
};
|
||
}
|
||
|
||
/** MSIN-4445 — Début obligatoire ; Fin/Qté optionnels (bounded=false → taille auto). */
|
||
function bibGetGlobalBatchGeneratedBounds(section) {
|
||
var fields = bibGetGlobalBatchGeneratedRangeFields(section);
|
||
if (!fields) {
|
||
return { start: 0, end: 0, qty: 0, bounded: false };
|
||
}
|
||
|
||
var start = bibRangeParseInt(fields.start && fields.start.value);
|
||
var qty = bibRangeParseInt(fields.qty && fields.qty.value);
|
||
var end = bibRangeParseInt(fields.end && fields.end.value);
|
||
var pilot = (fields.wrap && fields.wrap.dataset.rangePilot) || '';
|
||
|
||
if (start <= 0) {
|
||
return { start: 0, end: 0, qty: 0, bounded: false };
|
||
}
|
||
|
||
if (pilot === 'qty' && qty > 0) {
|
||
end = start + qty - 1;
|
||
return { start: start, end: end, qty: qty, bounded: true };
|
||
}
|
||
|
||
if (pilot === 'end' && end >= start) {
|
||
qty = end - start + 1;
|
||
return { start: start, end: end, qty: qty, bounded: true };
|
||
}
|
||
|
||
return { start: start, end: 0, qty: 0, bounded: false };
|
||
}
|
||
|
||
function bibFormatGlobalGeneratedQtyFeedback(qty, pending) {
|
||
var diff = qty - pending;
|
||
if (qty <= 0) {
|
||
return '';
|
||
}
|
||
if (diff === 0) {
|
||
return bibJs('jsGlobalFreeQtyJuste') || 'Quantité juste';
|
||
}
|
||
if (diff > 0) {
|
||
return bibJsFmt('jsGlobalFreeQtySupplementaire', diff)
|
||
|| (('Quantité supplémentaire : %d').replace('%d', String(diff)));
|
||
}
|
||
return bibJsFmt('jsGlobalFreeQtyManquante', Math.abs(diff))
|
||
|| (('Quantité manquante : %d').replace('%d', String(Math.abs(diff))));
|
||
}
|
||
|
||
function bibSetGlobalGeneratedDupesWarn(section, blnShow, strMessage) {
|
||
var fields = bibGetGlobalBatchGeneratedRangeFields(section);
|
||
if (!fields || !fields.dupesEl) {
|
||
return;
|
||
}
|
||
|
||
var msg = strMessage
|
||
|| bibJs('jsGlobalFreeDupesWarn')
|
||
|| 'Attention : vous êtes en train de créer des inscriptions avec des dossards en double.';
|
||
|
||
if (!blnShow) {
|
||
fields.dupesEl.textContent = '';
|
||
fields.dupesEl.classList.add('bib-ui-hidden');
|
||
} else {
|
||
fields.dupesEl.textContent = msg;
|
||
fields.dupesEl.classList.remove('bib-ui-hidden');
|
||
}
|
||
}
|
||
|
||
function bibUpdateGlobalGeneratedQtyFeedback(section) {
|
||
var fields = bibGetGlobalBatchGeneratedRangeFields(section);
|
||
if (!fields) {
|
||
return;
|
||
}
|
||
|
||
var bounds = bibGetGlobalBatchGeneratedBounds(section);
|
||
var pending = bibCollectGlobalBatchGeneratedPending();
|
||
var qtyEl = fields.qtyEl;
|
||
var autoEl = fields.autoEl;
|
||
|
||
if (autoEl) {
|
||
if (bounds.bounded) {
|
||
autoEl.classList.add('bib-ui-hidden');
|
||
} else {
|
||
autoEl.classList.remove('bib-ui-hidden');
|
||
}
|
||
}
|
||
|
||
if (!qtyEl) {
|
||
return;
|
||
}
|
||
|
||
qtyEl.classList.remove(
|
||
'bib-global-gen-range__feedback--juste',
|
||
'bib-global-gen-range__feedback--manquante',
|
||
'bib-global-gen-range__feedback--supplementaire'
|
||
);
|
||
|
||
if (!bounds.bounded) {
|
||
qtyEl.textContent = '';
|
||
bibSetGlobalGeneratedDupesWarn(section, false);
|
||
return;
|
||
}
|
||
|
||
var msg = bibFormatGlobalGeneratedQtyFeedback(bounds.qty, pending);
|
||
qtyEl.textContent = msg;
|
||
|
||
if (msg) {
|
||
if (bounds.qty === pending) {
|
||
qtyEl.classList.add('bib-global-gen-range__feedback--juste');
|
||
} else if (bounds.qty < pending) {
|
||
qtyEl.classList.add('bib-global-gen-range__feedback--manquante');
|
||
} else {
|
||
qtyEl.classList.add('bib-global-gen-range__feedback--supplementaire');
|
||
}
|
||
}
|
||
}
|
||
|
||
function bibSyncGlobalGeneratedRangeDerived(section) {
|
||
var fields = bibGetGlobalBatchGeneratedRangeFields(section);
|
||
if (!fields) {
|
||
return;
|
||
}
|
||
|
||
var start = bibRangeParseInt(fields.start && fields.start.value);
|
||
var pilot = (fields.wrap && fields.wrap.dataset.rangePilot) || '';
|
||
|
||
if (start <= 0) {
|
||
if (fields.qty) {
|
||
fields.qty.value = '';
|
||
fields.qty.disabled = true;
|
||
fields.qty.classList.remove('bib-field--active', 'bib-field--calc', 'bib-field--pick');
|
||
fields.qty.classList.add('bib-field--idle');
|
||
}
|
||
if (fields.end) {
|
||
fields.end.value = '';
|
||
fields.end.disabled = true;
|
||
fields.end.classList.remove('bib-field--active', 'bib-field--calc', 'bib-field--pick');
|
||
fields.end.classList.add('bib-field--idle');
|
||
}
|
||
if (fields.wrap) {
|
||
fields.wrap.dataset.rangePilot = '';
|
||
}
|
||
bibUpdateGlobalGeneratedQtyFeedback(section);
|
||
return;
|
||
}
|
||
|
||
if (!pilot) {
|
||
if (fields.qty) {
|
||
fields.qty.disabled = false;
|
||
fields.qty.classList.remove('bib-field--idle', 'bib-field--active', 'bib-field--calc');
|
||
fields.qty.classList.add('bib-field--pick');
|
||
}
|
||
if (fields.end) {
|
||
fields.end.disabled = false;
|
||
fields.end.classList.remove('bib-field--idle', 'bib-field--active', 'bib-field--calc');
|
||
fields.end.classList.add('bib-field--pick');
|
||
}
|
||
bibUpdateGlobalGeneratedQtyFeedback(section);
|
||
return;
|
||
}
|
||
|
||
if (pilot === 'qty') {
|
||
var qty = bibRangeParseInt(fields.qty && fields.qty.value);
|
||
if (fields.end) {
|
||
fields.end.disabled = true;
|
||
fields.end.classList.remove('bib-field--active', 'bib-field--pick', 'bib-field--idle');
|
||
fields.end.classList.add('bib-field--calc');
|
||
fields.end.value = qty > 0 ? String(start + qty - 1) : '';
|
||
}
|
||
if (fields.qty) {
|
||
fields.qty.disabled = false;
|
||
fields.qty.classList.remove('bib-field--idle', 'bib-field--calc', 'bib-field--pick');
|
||
fields.qty.classList.add('bib-field--active');
|
||
}
|
||
} else if (pilot === 'end') {
|
||
var end = bibRangeParseInt(fields.end && fields.end.value);
|
||
if (fields.qty) {
|
||
fields.qty.disabled = true;
|
||
fields.qty.classList.remove('bib-field--active', 'bib-field--pick', 'bib-field--idle');
|
||
fields.qty.classList.add('bib-field--calc');
|
||
fields.qty.value = (end >= start) ? String(end - start + 1) : '';
|
||
}
|
||
if (fields.end) {
|
||
fields.end.disabled = false;
|
||
fields.end.classList.remove('bib-field--idle', 'bib-field--calc', 'bib-field--pick');
|
||
fields.end.classList.add('bib-field--active');
|
||
}
|
||
}
|
||
|
||
bibUpdateGlobalGeneratedQtyFeedback(section);
|
||
}
|
||
|
||
function bibPickGlobalGeneratedPilot(section, pilot) {
|
||
var fields = bibGetGlobalBatchGeneratedRangeFields(section);
|
||
if (!fields || !fields.wrap) {
|
||
return;
|
||
}
|
||
|
||
var start = bibRangeParseInt(fields.start && fields.start.value);
|
||
if (start <= 0) {
|
||
return;
|
||
}
|
||
|
||
fields.wrap.dataset.rangePilot = pilot;
|
||
bibSyncGlobalGeneratedRangeDerived(section);
|
||
|
||
var target = pilot === 'qty' ? fields.qty : fields.end;
|
||
if (target && !target.disabled) {
|
||
target.focus();
|
||
}
|
||
}
|
||
|
||
function bibBindGlobalGeneratedRange(section) {
|
||
var fields = bibGetGlobalBatchGeneratedRangeFields(section);
|
||
if (!fields || !fields.wrap || fields.wrap.dataset.bound === '1') {
|
||
return;
|
||
}
|
||
fields.wrap.dataset.bound = '1';
|
||
|
||
if (fields.start) {
|
||
fields.start.addEventListener('input', function () {
|
||
bibSyncGlobalGeneratedRangeDerived(section);
|
||
updateGlobalBatchGeneratedAnalysis();
|
||
});
|
||
}
|
||
|
||
if (fields.qty) {
|
||
fields.qty.addEventListener('focus', function () {
|
||
bibPickGlobalGeneratedPilot(section, 'qty');
|
||
});
|
||
fields.qty.addEventListener('click', function () {
|
||
bibPickGlobalGeneratedPilot(section, 'qty');
|
||
});
|
||
fields.qty.addEventListener('input', function () {
|
||
if (fields.wrap.dataset.rangePilot !== 'qty') {
|
||
fields.wrap.dataset.rangePilot = 'qty';
|
||
}
|
||
bibSyncGlobalGeneratedRangeDerived(section);
|
||
updateGlobalBatchGeneratedAnalysis();
|
||
});
|
||
}
|
||
|
||
if (fields.end) {
|
||
fields.end.addEventListener('focus', function () {
|
||
bibPickGlobalGeneratedPilot(section, 'end');
|
||
});
|
||
fields.end.addEventListener('click', function () {
|
||
bibPickGlobalGeneratedPilot(section, 'end');
|
||
});
|
||
fields.end.addEventListener('input', function () {
|
||
if (fields.wrap.dataset.rangePilot !== 'end') {
|
||
fields.wrap.dataset.rangePilot = 'end';
|
||
}
|
||
bibSyncGlobalGeneratedRangeDerived(section);
|
||
updateGlobalBatchGeneratedAnalysis();
|
||
});
|
||
}
|
||
|
||
bibSyncGlobalGeneratedRangeDerived(section);
|
||
}
|
||
|
||
function bibAppendGlobalBatchGeneratedParams(body, section) {
|
||
var sortKeys = bibGetGlobalBatchSortKeys(section);
|
||
var bounds = bibGetGlobalBatchGeneratedBounds(section);
|
||
body = bibAppendBatchSortParams(body, sortKeys);
|
||
body += '&start_bib=' + encodeURIComponent(bounds.start);
|
||
body += '&end_bib=' + encodeURIComponent(bounds.bounded ? bounds.end : 0);
|
||
body += '&epr_ids=' + encodeURIComponent(JSON.stringify(bibCollectGlobalBatchGeneratedEprIds()));
|
||
return body;
|
||
}
|
||
|
||
function updateGlobalBatchGeneratedAnalysis() {
|
||
var section = bibGetGlobalBatchGeneratedSection();
|
||
if (!section) {
|
||
return Promise.resolve();
|
||
}
|
||
|
||
bibBindGlobalGeneratedRange(section);
|
||
|
||
var infoEl = section.querySelector('.bib-global-gen-batch__info');
|
||
var eprIds = bibCollectGlobalBatchGeneratedEprIds();
|
||
var bounds = bibGetGlobalBatchGeneratedBounds(section);
|
||
|
||
bibUpdateGlobalGeneratedQtyFeedback(section);
|
||
|
||
if (!infoEl) {
|
||
return Promise.resolve();
|
||
}
|
||
|
||
if (eprIds.length === 0) {
|
||
bibSetGlobalBatchInfo(
|
||
infoEl,
|
||
bibJs('jsGlobalNoEpr') || bibJs('jsBatchNone'),
|
||
'error'
|
||
);
|
||
bibSetGlobalGeneratedDupesWarn(section, false);
|
||
return Promise.resolve(null);
|
||
}
|
||
|
||
if (bounds.start <= 0) {
|
||
bibSetGlobalBatchInfo(
|
||
infoEl,
|
||
bibJs('jsGlobalGenNoStart') || bibJs('jsFieldsRequired'),
|
||
'error'
|
||
);
|
||
bibSetGlobalGeneratedDupesWarn(section, false);
|
||
return Promise.resolve(null);
|
||
}
|
||
|
||
bibSetGlobalBatchInfo(infoEl, bibJs('jsLoaderWait') || '…', 'normal');
|
||
|
||
return fetch('/ajax_bib_range.php', {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||
body: bibAppendGlobalBatchGeneratedParams(
|
||
'action=batch_global_gen_analysis'
|
||
+ '&eve_id=' + encodeURIComponent(moduleBib.dataset.eveId || ''),
|
||
section
|
||
) + bibAjaxLangSuffix()
|
||
})
|
||
.then(function (res) { return res.json(); })
|
||
.then(function (data) {
|
||
if (!data.success) {
|
||
bibSetGlobalBatchInfo(
|
||
infoEl,
|
||
data.message || bibJs('jsErrGeneric'),
|
||
'error'
|
||
);
|
||
bibSetGlobalGeneratedDupesWarn(section, false);
|
||
return data;
|
||
}
|
||
|
||
bibSetGlobalBatchInfo(infoEl, data.info || '', 'normal');
|
||
if (data.duplicates && data.duplicates.has) {
|
||
bibSetGlobalGeneratedDupesWarn(section, true, data.duplicates.message || '');
|
||
} else {
|
||
bibSetGlobalGeneratedDupesWarn(section, false);
|
||
}
|
||
return data;
|
||
})
|
||
.catch(function () {
|
||
bibSetGlobalBatchInfo(infoEl, bibJs('jsErrGeneric'), 'error');
|
||
return null;
|
||
});
|
||
}
|
||
|
||
function bibRunGlobalBatchGeneratedGo() {
|
||
var section = bibGetGlobalBatchGeneratedSection();
|
||
if (!section) {
|
||
return;
|
||
}
|
||
|
||
var eprIds = bibCollectGlobalBatchGeneratedEprIds();
|
||
var bounds = bibGetGlobalBatchGeneratedBounds(section);
|
||
var sortKeys = bibGetGlobalBatchSortKeys(section);
|
||
|
||
if (eprIds.length === 0) {
|
||
alert(bibJs('jsGlobalNoEpr') || bibJs('jsBatchNone'));
|
||
return;
|
||
}
|
||
|
||
if (bounds.start <= 0) {
|
||
alert(bibJs('jsGlobalGenNoStart') || bibJs('jsFieldsRequired'));
|
||
return;
|
||
}
|
||
|
||
fetch('/ajax_bib_range.php', {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||
body: bibAppendGlobalBatchGeneratedParams(
|
||
'action=batch_global_gen_create'
|
||
+ '&eve_id=' + encodeURIComponent(moduleBib.dataset.eveId || ''),
|
||
section
|
||
) + bibAjaxLangSuffix()
|
||
})
|
||
.then(function (res) {
|
||
if (!res.ok) {
|
||
throw new Error(bibJs('jsErrGeneric') || 'Erreur');
|
||
}
|
||
return res.json().catch(function () {
|
||
throw new Error(bibJs('jsServerError') || bibJs('jsErrGeneric') || 'Erreur serveur');
|
||
});
|
||
})
|
||
.then(function (createData) {
|
||
if (!createData || !createData.success || !Array.isArray(createData.plans) || createData.plans.length === 0) {
|
||
throw new Error((createData && createData.message) || bibJs('jsErrGeneric') || 'Erreur');
|
||
}
|
||
|
||
var plans = createData.plans;
|
||
var globalTotal = (createData.stats && createData.stats.nb_participants)
|
||
? createData.stats.nb_participants
|
||
: 1;
|
||
var completedOffset = 0;
|
||
var runResults = [];
|
||
|
||
bibBatchProgressShow(0, globalTotal);
|
||
|
||
var chain = Promise.resolve();
|
||
|
||
plans.forEach(function (plan) {
|
||
chain = chain.then(function () {
|
||
var row = moduleBib.querySelector('.epr-row[data-epr-id="' + plan.epr_id + '"]');
|
||
if (!row) {
|
||
throw new Error(
|
||
bibJs('jsGlobalGenEprMissing')
|
||
|| bibJs('jsErrGeneric')
|
||
|| 'Épreuve introuvable — rechargez la page.'
|
||
);
|
||
}
|
||
|
||
var pendingBefore = bibRowPendingBibs(row);
|
||
var offset = completedOffset;
|
||
|
||
return bibRunBatchApplyChunks(row, plan.ranges, sortKeys, {
|
||
showResult: false,
|
||
manageLoader: false,
|
||
deferUiRefresh: true,
|
||
totalInitial: pendingBefore,
|
||
onProgress: function (processed) {
|
||
bibBatchProgressShow(offset + processed, globalTotal);
|
||
}
|
||
}).then(function (data) {
|
||
runResults.push({
|
||
epr_id: plan.epr_id,
|
||
assigned: data.assigned_total || 0,
|
||
total: data.total_initial || pendingBefore
|
||
});
|
||
completedOffset = offset + pendingBefore;
|
||
});
|
||
});
|
||
});
|
||
|
||
return chain.then(function () {
|
||
bibBatchProgressShow(
|
||
globalTotal,
|
||
globalTotal,
|
||
bibJs('jsGlobalBatchFinalizing') || bibJs('jsLoaderWait')
|
||
);
|
||
|
||
var refreshChain = Promise.resolve();
|
||
runResults.forEach(function (result) {
|
||
refreshChain = refreshChain.then(function () {
|
||
var row = moduleBib.querySelector('.epr-row[data-epr-id="' + result.epr_id + '"]');
|
||
if (!row) {
|
||
return null;
|
||
}
|
||
return bibAfterBatchGoRefreshOnly(row, false, {
|
||
loader: false,
|
||
skipAnomalies: true,
|
||
skipQtySummary: true,
|
||
refreshLite: true,
|
||
skipSync: true
|
||
});
|
||
});
|
||
});
|
||
|
||
return refreshChain.then(function () {
|
||
if (typeof refreshBibAnomaliesPanel === 'function') {
|
||
return refreshBibAnomaliesPanel();
|
||
}
|
||
}).then(function () {
|
||
bibFinishGlobalBatchGo(runResults);
|
||
});
|
||
});
|
||
})
|
||
.catch(function (err) {
|
||
alert(err.message || bibJs('jsErrGeneric'));
|
||
})
|
||
.finally(function () {
|
||
bibBatchProgressForceHide();
|
||
});
|
||
}
|
||
|
||
function bibRunGlobalBatchGo() {
|
||
var section = bibGetGlobalBatchExistingSection();
|
||
if (!section) {
|
||
return;
|
||
}
|
||
|
||
var plans = bibCollectGlobalBatchPlans();
|
||
var sortKeys = bibGetGlobalBatchSortKeys(section);
|
||
|
||
if (plans.length === 0) {
|
||
alert(bibJs('jsGlobalNoEpr') || bibJs('jsBatchNone'));
|
||
return;
|
||
}
|
||
|
||
if (!plans.some(function (p) { return p.ranges.length > 0; })) {
|
||
alert(bibJs('jsGlobalNoSeq') || bibJs('jsNoSeqSelected'));
|
||
return;
|
||
}
|
||
|
||
fetch('/ajax_bib_range.php', {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||
body:
|
||
'action=batch_global_analysis'
|
||
+ '&eve_id=' + encodeURIComponent(moduleBib.dataset.eveId || '')
|
||
+ bibAppendBatchSortParams('', sortKeys)
|
||
+ '&plans=' + encodeURIComponent(JSON.stringify(plans))
|
||
+ bibAjaxLangSuffix()
|
||
})
|
||
.then(function (res) {
|
||
if (!res.ok) {
|
||
throw new Error(bibJs('jsErrGeneric'));
|
||
}
|
||
return res.json();
|
||
})
|
||
.then(function (analysis) {
|
||
if (!analysis || !analysis.success) {
|
||
throw new Error((analysis && analysis.message) || bibJs('jsErrGeneric'));
|
||
}
|
||
|
||
var globalTotal = (analysis.stats && analysis.stats.nb_participants)
|
||
? analysis.stats.nb_participants
|
||
: 1;
|
||
var completedOffset = 0;
|
||
var runResults = [];
|
||
|
||
bibBatchProgressShow(0, globalTotal);
|
||
|
||
var chain = Promise.resolve();
|
||
|
||
plans.forEach(function (plan) {
|
||
chain = chain.then(function () {
|
||
var row = moduleBib.querySelector('.epr-row[data-epr-id="' + plan.epr_id + '"]');
|
||
if (!row) {
|
||
throw new Error(bibJs('jsErrGeneric'));
|
||
}
|
||
|
||
var pendingBefore = bibRowPendingBibs(row);
|
||
var offset = completedOffset;
|
||
|
||
return bibRunBatchApplyChunks(row, plan.ranges, sortKeys, {
|
||
showResult: false,
|
||
manageLoader: false,
|
||
deferUiRefresh: true,
|
||
totalInitial: pendingBefore,
|
||
onProgress: function (processed) {
|
||
bibBatchProgressShow(offset + processed, globalTotal);
|
||
}
|
||
}).then(function (data) {
|
||
runResults.push({
|
||
epr_id: plan.epr_id,
|
||
assigned: data.assigned_total || 0,
|
||
total: data.total_initial || pendingBefore
|
||
});
|
||
completedOffset = offset + pendingBefore;
|
||
});
|
||
});
|
||
});
|
||
|
||
return chain.then(function () {
|
||
bibBatchProgressShow(
|
||
globalTotal,
|
||
globalTotal,
|
||
bibJs('jsGlobalBatchFinalizing') || bibJs('jsLoaderWait')
|
||
);
|
||
|
||
var refreshChain = Promise.resolve();
|
||
runResults.forEach(function (result) {
|
||
refreshChain = refreshChain.then(function () {
|
||
var row = moduleBib.querySelector('.epr-row[data-epr-id="' + result.epr_id + '"]');
|
||
if (!row) {
|
||
return null;
|
||
}
|
||
return bibAfterBatchGoRefreshOnly(row, false, {
|
||
loader: false,
|
||
skipAnomalies: true,
|
||
skipQtySummary: true,
|
||
refreshLite: true,
|
||
skipSync: true
|
||
});
|
||
});
|
||
});
|
||
|
||
return refreshChain.then(function () {
|
||
if (typeof refreshBibAnomaliesPanel === 'function') {
|
||
return refreshBibAnomaliesPanel();
|
||
}
|
||
}).then(function () {
|
||
bibFinishGlobalBatchGo(runResults);
|
||
});
|
||
});
|
||
})
|
||
.catch(function (err) {
|
||
alert(err.message || bibJs('jsErrGeneric'));
|
||
})
|
||
.finally(function () {
|
||
bibBatchProgressForceHide();
|
||
});
|
||
}
|
||
|
||
moduleBib.addEventListener('keydown', function (e) {
|
||
if (e.key !== 'Enter' && e.key !== ' ') {
|
||
return;
|
||
}
|
||
var workspaceTab = e.target.closest('.bib-workspace-tab[role="tab"]');
|
||
if (workspaceTab && moduleBib.contains(workspaceTab)) {
|
||
e.preventDefault();
|
||
bibSetWorkspace(workspaceTab.getAttribute('data-bib-workspace'));
|
||
return;
|
||
}
|
||
var toolBtn = e.target.closest('.bib-tool-btn[role="button"]');
|
||
if (!toolBtn || !moduleBib.contains(toolBtn)) {
|
||
return;
|
||
}
|
||
e.preventDefault();
|
||
bibOpenTool(toolBtn.getAttribute('data-bib-tool'));
|
||
});
|
||
|
||
// MSIN-4469 — Le téléchargement part dans un nouvel onglet;
|
||
// l’écran principal revient aussitôt à Quantités et assignation.
|
||
// MSIN-4515 — Serialize data-item-key / data-item-side via UI kit chooser.
|
||
function bibProdFieldsPanel() {
|
||
return moduleBib.querySelector('.bib-production-fields');
|
||
}
|
||
|
||
function bibProdFieldsChooser() {
|
||
var panel = bibProdFieldsPanel();
|
||
if (!panel) {
|
||
return null;
|
||
}
|
||
return panel.querySelector('.ms1-ui-chooser[data-ms1-ui-screen="bib-prod-fields"]')
|
||
|| panel.querySelector('.ms1-ui-chooser');
|
||
}
|
||
|
||
function bibProdFieldsLabel(attr, fallback) {
|
||
var panel = bibProdFieldsPanel();
|
||
var val = panel ? panel.getAttribute(attr) : '';
|
||
return val || fallback;
|
||
}
|
||
|
||
function bibProdEscapeHtml(str) {
|
||
return String(str == null ? '' : str)
|
||
.replace(/&/g, '&')
|
||
.replace(/</g, '<')
|
||
.replace(/>/g, '>')
|
||
.replace(/"/g, '"');
|
||
}
|
||
|
||
function bibProdFieldsBuildPayload() {
|
||
var payload = {};
|
||
var chooser = bibProdFieldsChooser();
|
||
if (!chooser) {
|
||
return payload;
|
||
}
|
||
chooser.querySelectorAll('.ms1-ui-chooser-section[data-section-id]').forEach(function (section) {
|
||
var eprId = section.getAttribute('data-section-id') || '';
|
||
if (!eprId) {
|
||
return;
|
||
}
|
||
var rows = [];
|
||
section.querySelectorAll('.ms1-ui-chooser-selected-item').forEach(function (row) {
|
||
var key = String(row.getAttribute('data-item-key') || '');
|
||
var side = String(row.getAttribute('data-item-side') || '');
|
||
if (!key || !side) {
|
||
return;
|
||
}
|
||
rows.push({ key: key, side: side });
|
||
});
|
||
payload[eprId] = rows;
|
||
});
|
||
return payload;
|
||
}
|
||
|
||
function bibProdFieldsSerializeBody() {
|
||
return '&fields_json=' + encodeURIComponent(JSON.stringify(bibProdFieldsBuildPayload()));
|
||
}
|
||
|
||
function bibProdFieldsStatusMsg() {
|
||
var panel = bibProdFieldsPanel();
|
||
return panel ? panel.querySelector('.bib-production-fields-save-msg') : null;
|
||
}
|
||
|
||
// MSIN-4515 — Persist auto immédiat (JSON) ; alerte si échec.
|
||
var bibProdFieldsSaveTimer = null;
|
||
function bibProdFieldsSaveNow(statusText) {
|
||
var fieldsPanel = bibProdFieldsPanel();
|
||
if (!fieldsPanel || fieldsPanel.getAttribute('data-locked') === '1') {
|
||
return;
|
||
}
|
||
var eveId = fieldsPanel.getAttribute('data-eve-id') || '';
|
||
if (!eveId) {
|
||
return;
|
||
}
|
||
var msg = bibProdFieldsStatusMsg();
|
||
var body = 'action=production_fields_save'
|
||
+ '&eve_id=' + encodeURIComponent(eveId)
|
||
+ bibAjaxLangSuffix()
|
||
+ bibProdFieldsSerializeBody();
|
||
fetch('/ajax_bib_range.php', {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' },
|
||
body: body,
|
||
credentials: 'same-origin'
|
||
})
|
||
.then(function (res) { return res.json(); })
|
||
.then(function (result) {
|
||
if (result && result.success) {
|
||
if (msg) {
|
||
msg.textContent = statusText
|
||
|| bibProdFieldsLabel('data-label-saved', 'Enregistré.');
|
||
}
|
||
return;
|
||
}
|
||
var err = (result && result.message)
|
||
|| (bibJs('jsErrGeneric') || 'Erreur');
|
||
if (msg) {
|
||
msg.textContent = err;
|
||
}
|
||
alert(err);
|
||
})
|
||
.catch(function () {
|
||
var err = bibJs('jsServerError')
|
||
|| bibJs('jsErrGeneric')
|
||
|| 'Erreur serveur';
|
||
if (msg) {
|
||
msg.textContent = err;
|
||
}
|
||
alert(err);
|
||
});
|
||
}
|
||
|
||
function bibProdFieldsSaveSoon(statusText) {
|
||
if (bibProdFieldsSaveTimer) {
|
||
clearTimeout(bibProdFieldsSaveTimer);
|
||
}
|
||
bibProdFieldsSaveTimer = setTimeout(function () {
|
||
bibProdFieldsSaveTimer = null;
|
||
bibProdFieldsSaveNow(statusText);
|
||
}, 0);
|
||
}
|
||
|
||
/** MSIN-4515 — mockup A + Face/Endos/Info via MS1UiChooser (réessaie si script pas prêt). */
|
||
function initBibProductionFieldsChooser(root) {
|
||
var scope = (root && root.querySelector) ? root : moduleBib;
|
||
var fieldsPanel = scope.querySelector('.bib-production-fields')
|
||
|| moduleBib.querySelector('.bib-production-fields');
|
||
if (!fieldsPanel) {
|
||
return false;
|
||
}
|
||
var chooser = fieldsPanel.querySelector('.ms1-ui-chooser[data-ms1-ui-screen="bib-prod-fields"]')
|
||
|| fieldsPanel.querySelector('.ms1-ui-chooser');
|
||
if (!chooser) {
|
||
return false;
|
||
}
|
||
// Déjà branché et vivant.
|
||
if (chooser._ms1UiChooser) {
|
||
return true;
|
||
}
|
||
if (!window.MS1UiChooser || typeof window.MS1UiChooser.init !== 'function') {
|
||
if (!fieldsPanel.getAttribute('data-bib-prod-chooser-retry')) {
|
||
fieldsPanel.setAttribute('data-bib-prod-chooser-retry', '1');
|
||
window.setTimeout(function () {
|
||
fieldsPanel.removeAttribute('data-bib-prod-chooser-retry');
|
||
initBibProductionFieldsChooser(scope);
|
||
}, 120);
|
||
}
|
||
return false;
|
||
}
|
||
|
||
var sideOptions = [];
|
||
try {
|
||
sideOptions = JSON.parse(chooser.getAttribute('data-side-options') || '[]');
|
||
} catch (err) {
|
||
sideOptions = [];
|
||
}
|
||
|
||
var blnLocked = fieldsPanel.getAttribute('data-locked') === '1'
|
||
|| chooser.getAttribute('data-locked') === '1'
|
||
|| chooser.getAttribute('data-side-locked') === '1';
|
||
|
||
try {
|
||
chooser.removeAttribute('data-ms1-ui-chooser-init');
|
||
chooser._ms1UiChooser = null;
|
||
window.MS1UiChooser.init(chooser, {
|
||
getBudget: function () { return null; },
|
||
labelRemove: fieldsPanel.getAttribute('data-label-remove') || '',
|
||
sideOptions: sideOptions,
|
||
defaultSide: chooser.getAttribute('data-default-side') || 'face',
|
||
sideLocked: blnLocked,
|
||
onChange: function (_root, reason) {
|
||
if (fieldsPanel.getAttribute('data-locked') === '1') {
|
||
return;
|
||
}
|
||
if (reason === 'apply') {
|
||
bibProdFieldsSaveNow(bibProdFieldsLabel(
|
||
'data-label-apply-done',
|
||
'Choix de la 1re épreuve appliqués aux autres.'
|
||
));
|
||
return;
|
||
}
|
||
bibProdFieldsSaveSoon();
|
||
}
|
||
});
|
||
} catch (errInit) {
|
||
chooser.removeAttribute('data-ms1-ui-chooser-init');
|
||
chooser._ms1UiChooser = null;
|
||
return false;
|
||
}
|
||
return !!chooser._ms1UiChooser;
|
||
}
|
||
|
||
var bibProdPanelPollTimer = null;
|
||
var bibProdPanelPollAttempts = 0;
|
||
|
||
function bibProdStopPanelPoll() {
|
||
if (bibProdPanelPollTimer) {
|
||
clearTimeout(bibProdPanelPollTimer);
|
||
bibProdPanelPollTimer = null;
|
||
}
|
||
bibProdPanelPollAttempts = 0;
|
||
}
|
||
|
||
/** MSIN-4515 — Recharge le panneau Production (Télécharger / Déverrouiller) sans F5. */
|
||
function bibProdReloadProductionPanelHtml() {
|
||
var panel = moduleBib.querySelector('[data-bib-workspace-panel="production"]');
|
||
var mount = document.getElementById('bib-production-mount');
|
||
if (!panel || !mount) {
|
||
return Promise.resolve(false);
|
||
}
|
||
return bibFetch('/ajax_bib_range.php', {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||
body: 'action=production_panel'
|
||
+ '&eve_id=' + encodeURIComponent(moduleBib.dataset.eveId || '')
|
||
+ bibAjaxLangSuffix()
|
||
}, { loader: false })
|
||
.then(function (res) { return res.json(); })
|
||
.then(function (data) {
|
||
if (!data || !data.success || !data.html) {
|
||
return false;
|
||
}
|
||
mount.innerHTML = data.html;
|
||
panel.setAttribute('data-production-loaded', '1');
|
||
initModuleBibTippy(panel);
|
||
initBibProductionFieldsChooser(panel);
|
||
return true;
|
||
})
|
||
.catch(function () {
|
||
return false;
|
||
});
|
||
}
|
||
|
||
/**
|
||
* MSIN-4515 — Après generate : poll jusqu’à voir Déverrouiller (+ Télécharger quand prêt).
|
||
*/
|
||
function bibProdPollProductionPanelAfterGenerate() {
|
||
bibProdStopPanelPoll();
|
||
bibProdPanelPollAttempts = 0;
|
||
|
||
function schedule(ms) {
|
||
bibProdPanelPollTimer = setTimeout(run, ms);
|
||
}
|
||
|
||
function run() {
|
||
bibProdPanelPollAttempts += 1;
|
||
bibProdReloadProductionPanelHtml().then(function (ok) {
|
||
var mount = document.getElementById('bib-production-mount');
|
||
if (!mount) {
|
||
return;
|
||
}
|
||
var hasUnlock = !!mount.querySelector('input[name="action"][value="development_unlock"]');
|
||
var hasDownload = !!mount.querySelector('input[name="action"][value="download"]');
|
||
var stillGenerate = !!mount.querySelector('#bib-production-generate-form');
|
||
|
||
if (hasUnlock || hasDownload) {
|
||
if (hasDownload || bibProdPanelPollAttempts >= 36) {
|
||
bibProdStopPanelPoll();
|
||
return;
|
||
}
|
||
// Verrouillé mais Excel encore « generating » → continuer jusqu’au download.
|
||
schedule(2500);
|
||
return;
|
||
}
|
||
if (stillGenerate && bibProdPanelPollAttempts < 36) {
|
||
schedule(2500);
|
||
return;
|
||
}
|
||
if (bibProdPanelPollAttempts < 36) {
|
||
schedule(2500);
|
||
return;
|
||
}
|
||
bibProdStopPanelPoll();
|
||
});
|
||
}
|
||
|
||
// Premier refresh rapidement (commande déjà créée / verrou en BD).
|
||
schedule(1200);
|
||
}
|
||
|
||
moduleBib.addEventListener('submit', function (e) {
|
||
var productionForm = e.target.closest('.bib-production-return-preparation-form');
|
||
if (productionForm && moduleBib.contains(productionForm)) {
|
||
// MSIN-4515 / MSIN-4469 — Générer Excel (target=_blank).
|
||
// IMPORTANT : ne PAS retirer le form / disable le bouton pendant le submit
|
||
// (ça annulait le POST → flash reload + aucun fichier).
|
||
if (productionForm.classList.contains('bib-production-generate-form')) {
|
||
if (productionForm.getAttribute('data-submitted') === '1') {
|
||
e.preventDefault();
|
||
return;
|
||
}
|
||
productionForm.setAttribute('data-submitted', '1');
|
||
|
||
var host = productionForm.querySelector('.bib-production-generate-fields-host');
|
||
if (host) {
|
||
host.innerHTML = '';
|
||
var hidden = document.createElement('input');
|
||
hidden.type = 'hidden';
|
||
hidden.name = 'fields_json';
|
||
hidden.value = JSON.stringify(bibProdFieldsBuildPayload());
|
||
host.appendChild(hidden);
|
||
}
|
||
|
||
// Après que le navigateur ait lancé le POST vers le nouvel onglet.
|
||
setTimeout(function () {
|
||
var genBtn = productionForm.querySelector('button[type="submit"]');
|
||
if (genBtn) {
|
||
genBtn.disabled = true;
|
||
}
|
||
bibProdUiMarkLockedAfterGenerate(false);
|
||
bibProdPollProductionPanelAfterGenerate();
|
||
}, 0);
|
||
|
||
try {
|
||
window.sessionStorage.setItem('ms1_bib_workspace', 'production');
|
||
} catch (errWs) { /* ignore */ }
|
||
}
|
||
bibSetWorkspace('production');
|
||
}
|
||
});
|
||
|
||
/**
|
||
* MSIN-4515 — Verrouille l’UI locale après generate.
|
||
* @param {boolean} blnRemoveForm — false pendant submit (garder le form pour le POST).
|
||
*/
|
||
function bibProdUiMarkLockedAfterGenerate(blnRemoveForm) {
|
||
var genForm = moduleBib.querySelector('#bib-production-generate-form');
|
||
if (genForm && blnRemoveForm) {
|
||
var lockedHtml = '<p class="bib-production-category__status">'
|
||
+ '<i class="fa fa-lock mr-1" aria-hidden="true"></i>'
|
||
+ bibProdEscapeHtml(bibProdFieldsLabel(
|
||
'data-label-excel-locked',
|
||
'En impression — séquences verrouillées'
|
||
))
|
||
+ '</p>';
|
||
genForm.insertAdjacentHTML('beforebegin', lockedHtml);
|
||
genForm.remove();
|
||
} else if (genForm && !blnRemoveForm) {
|
||
var status = genForm.previousElementSibling;
|
||
if (!status || !status.classList.contains('bib-production-category__status')) {
|
||
genForm.insertAdjacentHTML(
|
||
'beforebegin',
|
||
'<p class="bib-production-category__status">'
|
||
+ '<i class="fa fa-lock mr-1" aria-hidden="true"></i>'
|
||
+ bibProdEscapeHtml(bibProdFieldsLabel(
|
||
'data-label-excel-locked',
|
||
'En impression — séquences verrouillées'
|
||
))
|
||
+ '</p>'
|
||
);
|
||
}
|
||
genForm.style.display = 'none';
|
||
}
|
||
var fieldsPanel = bibProdFieldsPanel();
|
||
if (fieldsPanel) {
|
||
fieldsPanel.setAttribute('data-locked', '1');
|
||
}
|
||
var chooser = bibProdFieldsChooser();
|
||
if (chooser) {
|
||
chooser.setAttribute('data-locked', '1');
|
||
chooser.setAttribute('data-side-locked', '1');
|
||
}
|
||
moduleBib.querySelectorAll(
|
||
'.ms1-ui-chooser-apply-all, .ms1-ui-chooser-selected-remove, .ms1-ui-chooser-chip'
|
||
).forEach(function (el) {
|
||
if (fieldsPanel && fieldsPanel.contains(el)) {
|
||
el.remove();
|
||
}
|
||
});
|
||
}
|
||
|
||
moduleBib.addEventListener('click', function (e) {
|
||
var workspaceTab = e.target.closest('.bib-workspace-tab');
|
||
if (workspaceTab && moduleBib.contains(workspaceTab)) {
|
||
if (e.target.closest('.btn-aide-trad, .btn-trad-admin, .ms1-trad-link')) {
|
||
return;
|
||
}
|
||
e.preventDefault();
|
||
bibSetWorkspace(workspaceTab.getAttribute('data-bib-workspace'));
|
||
return;
|
||
}
|
||
|
||
if (e.target.closest('.btn-global-batch-complete-reload')) {
|
||
e.preventDefault();
|
||
location.reload();
|
||
return;
|
||
}
|
||
|
||
if (e.target.closest('.bib-tool-detail__close')) {
|
||
e.preventDefault();
|
||
bibCloseTool({ returnToPreparation: true });
|
||
return;
|
||
}
|
||
|
||
var toolBtn = e.target.closest('.bib-tool-btn');
|
||
if (toolBtn && moduleBib.contains(toolBtn)) {
|
||
if (e.target.closest('.btn-aide-bib, .bib-aide-trigger, .btn-aide-trad, .btn-doc-trigger, .btn-admin-doc, .btn-trad-admin')) {
|
||
return;
|
||
}
|
||
e.preventDefault();
|
||
bibOpenTool(toolBtn.getAttribute('data-bib-tool'));
|
||
return;
|
||
}
|
||
|
||
if (e.target.closest('.btn-simuler-global-batch')) {
|
||
e.preventDefault();
|
||
var existingSection = bibGetGlobalBatchExistingSection();
|
||
var plans = bibCollectGlobalBatchPlans();
|
||
var sortKeys = existingSection
|
||
? bibGetGlobalBatchSortKeys(existingSection)
|
||
: { sort1: '', sort2: '' };
|
||
|
||
if (plans.length === 0) {
|
||
alert(bibJs('jsGlobalNoEpr') || bibJs('jsBatchNone'));
|
||
return;
|
||
}
|
||
|
||
bibFetch('/ajax_bib_range.php', {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||
body:
|
||
'action=batch_global_simulate'
|
||
+ '&eve_id=' + encodeURIComponent(moduleBib.dataset.eveId || '')
|
||
+ bibAppendBatchSortParams('', sortKeys)
|
||
+ '&plans=' + encodeURIComponent(JSON.stringify(plans))
|
||
+ bibAjaxLangSuffix()
|
||
})
|
||
.then(function (res) { return res.json(); })
|
||
.then(function (data) {
|
||
if (!data.success) {
|
||
alert(data.message || bibJs('jsErrGeneric'));
|
||
return;
|
||
}
|
||
|
||
bibInsertGlobalSimView(data.html);
|
||
});
|
||
|
||
return;
|
||
}
|
||
|
||
if (e.target.closest('.btn-simuler-global-gen-batch')) {
|
||
e.preventDefault();
|
||
var genSection = bibGetGlobalBatchGeneratedSection();
|
||
var eprIds = bibCollectGlobalBatchGeneratedEprIds();
|
||
var genBounds = bibGetGlobalBatchGeneratedBounds(genSection);
|
||
|
||
if (eprIds.length === 0) {
|
||
alert(bibJs('jsGlobalNoEpr') || bibJs('jsBatchNone'));
|
||
return;
|
||
}
|
||
|
||
if (genBounds.start <= 0) {
|
||
alert(bibJs('jsGlobalGenNoStart') || bibJs('jsFieldsRequired'));
|
||
return;
|
||
}
|
||
|
||
bibFetch('/ajax_bib_range.php', {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||
body: bibAppendGlobalBatchGeneratedParams(
|
||
'action=batch_global_gen_simulate'
|
||
+ '&eve_id=' + encodeURIComponent(moduleBib.dataset.eveId || ''),
|
||
genSection
|
||
) + bibAjaxLangSuffix()
|
||
})
|
||
.then(function (res) { return res.json(); })
|
||
.then(function (data) {
|
||
if (!data.success) {
|
||
alert(data.message || bibJs('jsErrGeneric'));
|
||
return;
|
||
}
|
||
|
||
bibInsertGlobalSimView(data.html);
|
||
});
|
||
|
||
return;
|
||
}
|
||
|
||
if (e.target.closest('.btn-go-global-batch')) {
|
||
e.preventDefault();
|
||
bibRunGlobalBatchGo();
|
||
return;
|
||
}
|
||
|
||
if (e.target.closest('.btn-go-global-gen-batch')) {
|
||
e.preventDefault();
|
||
bibRunGlobalBatchGeneratedGo();
|
||
return;
|
||
}
|
||
});
|
||
|
||
moduleBib.addEventListener('change', function (e) {
|
||
if (!e.target.matches(
|
||
'.bib-global-epr-select, .bib-global-range-select, .bib-global-batch-order, .bib-global-batch-order-2,'
|
||
+ ' .bib-global-batch-order-3, .bib-global-batch-order-4,'
|
||
+ ' .bib-global-gen-epr-select, .bib-global-gen-batch-order, .bib-global-gen-batch-order-2,'
|
||
+ ' .bib-global-gen-batch-order-3, .bib-global-gen-batch-order-4,'
|
||
+ ' .bib-global-gen-start, .bib-global-gen-qty, .bib-global-gen-end'
|
||
)) {
|
||
return;
|
||
}
|
||
|
||
var bibGlobalBatchPanel = bibGetGlobalBatchBody();
|
||
if (!bibGlobalBatchPanel || !bibGlobalBatchPanel.contains(e.target)) {
|
||
return;
|
||
}
|
||
|
||
if (e.target.closest('.bib-global-batch--existing')) {
|
||
var eprBlock = e.target.closest('.bib-global-epr');
|
||
if (eprBlock && e.target.classList.contains('bib-global-epr-select')) {
|
||
var checked = e.target.checked;
|
||
eprBlock.querySelectorAll('.bib-global-range-select').forEach(function (cb) {
|
||
cb.disabled = !checked;
|
||
if (!checked) {
|
||
cb.checked = false;
|
||
}
|
||
});
|
||
}
|
||
updateGlobalBatchAnalysis();
|
||
return;
|
||
}
|
||
|
||
if (e.target.closest('.bib-global-batch--generated')) {
|
||
updateGlobalBatchGeneratedAnalysis();
|
||
return;
|
||
}
|
||
|
||
});
|
||
|
||
function bibRowPendingBibs(row) {
|
||
if (!row) return 0;
|
||
return parseInt(row.dataset.bibAAssigner || '0', 10) || 0;
|
||
}
|
||
|
||
function bibRefreshPreparationOverview() {
|
||
var rows = Array.from(moduleBib.querySelectorAll('.epr-row[data-epr-id]'));
|
||
var total = 0;
|
||
var assigned = 0;
|
||
var pending = 0;
|
||
|
||
rows.forEach(function (raceRow) {
|
||
total += parseInt((raceRow.querySelector('.bib-race-summary-total') || {}).textContent || '0', 10) || 0;
|
||
assigned += parseInt((raceRow.querySelector('.bib-race-summary-assigned') || {}).textContent || '0', 10) || 0;
|
||
pending += parseInt((raceRow.querySelector('.bib-race-summary-pending') || {}).textContent || '0', 10) || 0;
|
||
});
|
||
|
||
var values = {
|
||
bib_v5_stat_races: rows.length,
|
||
bib_v5_stat_registered: total,
|
||
bib_v5_stat_assigned: assigned,
|
||
bib_v5_stat_pending: pending
|
||
};
|
||
Object.keys(values).forEach(function (key) {
|
||
var el = moduleBib.querySelector('[data-bib-overview-stat="' + key + '"]');
|
||
if (el) {
|
||
el.textContent = values[key];
|
||
}
|
||
});
|
||
}
|
||
|
||
function bibSyncRaceSummaryStatus(row) {
|
||
if (!row) return;
|
||
bibRefreshPreparationOverview();
|
||
}
|
||
|
||
function bibSyncEprBibStats(row, info) {
|
||
if (!row || !info) return;
|
||
|
||
if (info.total !== undefined) {
|
||
let totalEl = row.querySelector('.bib-total');
|
||
if (totalEl) totalEl.textContent = info.total;
|
||
let summaryTotal = row.querySelector('.bib-race-summary-total');
|
||
if (summaryTotal) summaryTotal.textContent = info.total;
|
||
}
|
||
if (info.avec_bib !== undefined) {
|
||
let avecEl = row.querySelector('.bib-avec');
|
||
if (avecEl) avecEl.textContent = info.avec_bib;
|
||
let summaryAssigned = row.querySelector('.bib-race-summary-assigned');
|
||
if (summaryAssigned) summaryAssigned.textContent = info.avec_bib;
|
||
}
|
||
|
||
let pending = (info.a_assigner !== undefined && info.a_assigner !== null)
|
||
? info.a_assigner
|
||
: (info.sans_bib || 0);
|
||
row.dataset.bibAAssigner = String(parseInt(pending, 10) || 0);
|
||
let summaryPending = row.querySelector('.bib-race-summary-pending');
|
||
if (summaryPending) summaryPending.textContent = parseInt(pending, 10) || 0;
|
||
bibSyncRaceSummaryStatus(row);
|
||
}
|
||
|
||
function bibAlertAutoPendingBibs(row) {
|
||
alert(bibJsFmt('jsAutoPendingBibs', bibRowPendingBibs(row)).replace(/\\n/g, '\n'));
|
||
}
|
||
|
||
/** Bloque l'entrée en mode auto si des inscriptions n'ont pas encore de dossard. */
|
||
function bibBlockAutoActivation(row) {
|
||
if (!row || row.dataset.autoActive === '1') {
|
||
return false;
|
||
}
|
||
if (bibRowPendingBibs(row) > 0) {
|
||
bibAlertAutoPendingBibs(row);
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/** MSIN-4469 — Cadenas impression (bleu) a préséance sur le cadenas humain. */
|
||
function bibRowIsProductionLocked(row) {
|
||
if (!row) {
|
||
return false;
|
||
}
|
||
if (row.getAttribute('data-production-locked') === '1') {
|
||
return true;
|
||
}
|
||
return !!row.querySelector('.btn-bib-production-lock, .bib-range[data-production-locked="1"]');
|
||
}
|
||
|
||
function bibAlertProductionLocked() {
|
||
alert(bibJsConfirm('jsProductionLocked'));
|
||
}
|
||
|
||
/** Remet readonly seulement là où le verrou (humain ou impression) s'applique. */
|
||
function bibApplyRangeInputLockState(row) {
|
||
if (!row) {
|
||
return;
|
||
}
|
||
row.querySelectorAll('.bib-range.epr-line').forEach(function (line) {
|
||
var locked = line.dataset.locked === '1';
|
||
line.querySelectorAll('.bib-start, .bib-qty, .bib-end').forEach(function (input) {
|
||
if (locked) {
|
||
input.setAttribute('readonly', 'readonly');
|
||
} else {
|
||
input.removeAttribute('readonly');
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
// MSIN-4468 — Met à jour la capacité totale éditable et la disponibilité calculée.
|
||
function bibApplyQteData(data) {
|
||
if (!data || typeof data !== 'object') {
|
||
return;
|
||
}
|
||
|
||
Object.keys(data).forEach(function (eprId) {
|
||
if (eprId === 'total') {
|
||
return;
|
||
}
|
||
|
||
let row = data[eprId];
|
||
if (!row) {
|
||
return;
|
||
}
|
||
|
||
let elTotale = document.getElementById('qte_totale_' + eprId);
|
||
let elCourante = document.getElementById('qte_courante_' + eprId);
|
||
let elInscrits = document.getElementById('qte_inscrits_' + eprId);
|
||
let elCheckin = document.getElementById('qte_checkin_' + eprId);
|
||
let elRestante = document.getElementById('qte_restante_' + eprId);
|
||
|
||
if (elTotale) {
|
||
elTotale.value = row.qte_courante;
|
||
}
|
||
if (elCourante) {
|
||
elCourante.textContent = row.qte_courante;
|
||
}
|
||
if (elInscrits) {
|
||
elInscrits.textContent = row.qte_inscrits;
|
||
}
|
||
let gestionPanel = document.querySelector(
|
||
'.epr-gestion-panel[data-epr-id="' + eprId + '"]'
|
||
);
|
||
if (gestionPanel && row.qte_inscrits !== undefined) {
|
||
gestionPanel.dataset.qteInscrits = row.qte_inscrits;
|
||
}
|
||
if (elCheckin) {
|
||
elCheckin.textContent = row.qte_checkin;
|
||
}
|
||
if (elRestante) {
|
||
elRestante.textContent = row.qte_restante;
|
||
}
|
||
let summaryAvailable = document.querySelector(
|
||
'.epr-row[data-epr-id="' + eprId + '"] .bib-race-summary-available'
|
||
);
|
||
if (summaryAvailable && row.qte_restante !== undefined) {
|
||
summaryAvailable.textContent = row.qte_restante;
|
||
}
|
||
|
||
let dispoBadge = document.querySelector(
|
||
'.epr-row[data-epr-id="' + eprId + '"] .epr-header-summary--dispo'
|
||
);
|
||
if (dispoBadge && row.qte_restante !== undefined) {
|
||
let labelParts = dispoBadge.textContent.split(':');
|
||
let label = labelParts.length > 1 ? labelParts[0].trim() : '';
|
||
dispoBadge.textContent = label + ' : ' + row.qte_restante;
|
||
}
|
||
|
||
let btnQteTotal = document.querySelector(
|
||
'.epr-gestion-panel[data-epr-id="' + eprId + '"] .btn_qte_total'
|
||
);
|
||
if (btnQteTotal) {
|
||
btnQteTotal.setAttribute('data-qte_initiale', row.qte_courante);
|
||
}
|
||
});
|
||
}
|
||
|
||
function bibSaveQteTotal(btn) {
|
||
let eprId = btn.getAttribute('data-epr_id');
|
||
if (!eprId) {
|
||
return;
|
||
}
|
||
|
||
let input = document.getElementById('qte_totale_' + eprId);
|
||
if (!input) {
|
||
return;
|
||
}
|
||
|
||
let strQteTotale = String(input.value || '').trim();
|
||
let intQteTotale = Number(strQteTotale);
|
||
if (!/^\d+$/.test(strQteTotale)
|
||
|| !Number.isSafeInteger(intQteTotale)
|
||
|| intQteTotale > 9999999) {
|
||
// MSIN-4479 — data-js-err-generic → dataset.jsErrGeneric
|
||
alert(bibJs('jsErrGeneric') || 'Erreur');
|
||
return;
|
||
}
|
||
|
||
let gestionPanel = btn.closest('.epr-gestion-panel');
|
||
let intNbInscriptions = gestionPanel
|
||
? parseInt(gestionPanel.dataset.qteInscrits, 10) || 0
|
||
: 0;
|
||
if (intQteTotale < intNbInscriptions) {
|
||
alert(bibJsFmt('jsQteTotalMin', intNbInscriptions));
|
||
return;
|
||
}
|
||
|
||
bibLoaderShow();
|
||
fetch('/ajax_promoteur.php', {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/x-www-form-urlencoded'
|
||
},
|
||
credentials: 'same-origin',
|
||
body:
|
||
'a=qte_total'
|
||
+ '&epr_id=' + encodeURIComponent(eprId)
|
||
+ '&total=' + encodeURIComponent(intQteTotale)
|
||
+ '&lang=' + encodeURIComponent(moduleBib.dataset.lang || 'fr')
|
||
+ '&csrf_token=' + encodeURIComponent(moduleBib.dataset.csrfToken || '')
|
||
})
|
||
.then(function (res) {
|
||
return res.json();
|
||
})
|
||
.then(function (result) {
|
||
if (result && result.state === 'success' && result.data) {
|
||
bibApplyQteData(result.data);
|
||
return;
|
||
}
|
||
alert((result && result.message) || bibJs('jsErrGeneric') || 'Erreur');
|
||
})
|
||
.catch(function () {
|
||
alert(bibJs('jsServerError') || bibJs('jsErrGeneric') || 'Erreur serveur');
|
||
})
|
||
.finally(function () {
|
||
bibLoaderHide();
|
||
});
|
||
}
|
||
|
||
// MSIN-4379 — Réduire / développer les blocs gestion, assignation et sections anomalies.
|
||
function bibSetRaceRowExpanded(row, expanded) {
|
||
if (!row) {
|
||
return;
|
||
}
|
||
row.classList.toggle('is-expanded', expanded);
|
||
var summary = row.querySelector('.bib-race-summary');
|
||
var button = row.querySelector('.bib-race-toggle');
|
||
if (summary) {
|
||
summary.setAttribute('aria-expanded', expanded ? 'true' : 'false');
|
||
}
|
||
if (button) {
|
||
var label = button.getAttribute(expanded ? 'data-label-collapse' : 'data-label-expand') || '';
|
||
if (label) {
|
||
button.setAttribute('aria-label', label);
|
||
button.setAttribute('title', label);
|
||
}
|
||
var icon = button.querySelector('.fa');
|
||
if (icon) {
|
||
icon.classList.toggle('fa-chevron-up', expanded);
|
||
icon.classList.toggle('fa-chevron-down', !expanded);
|
||
}
|
||
}
|
||
}
|
||
|
||
function bibToggleRaceRow(row) {
|
||
if (!row) {
|
||
return;
|
||
}
|
||
var willExpand = !row.classList.contains('is-expanded');
|
||
if (willExpand) {
|
||
moduleBib.querySelectorAll('.epr-row.is-expanded').forEach(function (otherRow) {
|
||
if (otherRow !== row) {
|
||
bibSetRaceRowExpanded(otherRow, false);
|
||
}
|
||
});
|
||
}
|
||
bibSetRaceRowExpanded(row, willExpand);
|
||
// MSIN-4546 — Détail épreuve chargé à la première ouverture.
|
||
if (willExpand) {
|
||
bibEnsureRaceDetailLoaded(row);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* MSIN-4546 — Charge le panneau éditable d'une épreuve (1re ouverture).
|
||
*/
|
||
function bibEnsureRaceDetailLoaded(row) {
|
||
if (!row || !moduleBib) {
|
||
return Promise.resolve();
|
||
}
|
||
if (row.getAttribute('data-race-detail-deferred') !== '1') {
|
||
return Promise.resolve();
|
||
}
|
||
if (row.getAttribute('data-race-detail-loading') === '1'
|
||
|| row.getAttribute('data-race-detail-loaded') === '1') {
|
||
return Promise.resolve();
|
||
}
|
||
|
||
var mount = row.querySelector('[data-race-detail-mount="1"]');
|
||
var eprId = row.getAttribute('data-epr-id') || '';
|
||
var eveId = moduleBib.dataset.eveId || '';
|
||
if (!mount || !eprId) {
|
||
return Promise.resolve();
|
||
}
|
||
|
||
row.setAttribute('data-race-detail-loading', '1');
|
||
|
||
return bibFetch('/ajax_bib_range.php', {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/x-www-form-urlencoded'
|
||
},
|
||
body: 'action=race_detail'
|
||
+ '&epr_id=' + encodeURIComponent(eprId)
|
||
+ '&eve_id=' + encodeURIComponent(eveId)
|
||
+ bibAjaxLangSuffix()
|
||
}, { loader: false })
|
||
.then(function (res) { return res.json(); })
|
||
.then(function (data) {
|
||
if (!data || !data.success || !data.html) {
|
||
throw new Error((data && data.message) || bibJs('jsErrGeneric') || 'Erreur');
|
||
}
|
||
mount.innerHTML = data.html;
|
||
mount.removeAttribute('data-race-detail-deferred');
|
||
row.removeAttribute('data-race-detail-deferred');
|
||
row.setAttribute('data-race-detail-loaded', '1');
|
||
if (typeof data.auto_active !== 'undefined') {
|
||
row.setAttribute('data-auto-active', data.auto_active ? '1' : '0');
|
||
row.classList.toggle('auto-enabled', !!data.auto_active);
|
||
}
|
||
if (typeof data.a_assigner !== 'undefined') {
|
||
row.setAttribute('data-bib-a-assigner', String(data.a_assigner));
|
||
}
|
||
initModuleBibTippy(mount);
|
||
initBibRangeRows(mount);
|
||
syncBibUiState(row);
|
||
})
|
||
.catch(function (err) {
|
||
var msg = (err && err.message) ? err.message : (bibJs('jsServerError') || 'Erreur serveur');
|
||
mount.innerHTML = '<div class="text-danger small" style="padding:12px;">'
|
||
+ bibTippyEscapeHtml(msg)
|
||
+ '</div>';
|
||
})
|
||
.finally(function () {
|
||
row.removeAttribute('data-race-detail-loading');
|
||
});
|
||
}
|
||
|
||
function bibToggleCollapsibleBlock(block, btnToggle) {
|
||
if (!block || !btnToggle) {
|
||
return;
|
||
}
|
||
let collapsed = block.classList.toggle('is-collapsed');
|
||
btnToggle.setAttribute('aria-expanded', collapsed ? 'false' : 'true');
|
||
let hdr = block.querySelector('.bib-anomaly-block-header')
|
||
|| block.querySelector('.bib-global-batch__section-header');
|
||
if (hdr) {
|
||
hdr.setAttribute('aria-expanded', collapsed ? 'false' : 'true');
|
||
}
|
||
let label = collapsed
|
||
? (btnToggle.getAttribute('data-label-expand') || '')
|
||
: (btnToggle.getAttribute('data-label-collapse') || '');
|
||
if (label) {
|
||
btnToggle.setAttribute('aria-label', label);
|
||
btnToggle.setAttribute('title', label);
|
||
}
|
||
let icon = btnToggle.querySelector('.fa');
|
||
if (icon) {
|
||
icon.classList.toggle('fa-chevron-up', !collapsed);
|
||
icon.classList.toggle('fa-chevron-down', collapsed);
|
||
}
|
||
}
|
||
|
||
/** MSIN-4467 — Accordéon du détail : au plus un panneau ouvert, mais les deux peuvent être fermés. */
|
||
function bibActivateRaceDetailBlock(block) {
|
||
if (!block) {
|
||
return;
|
||
}
|
||
|
||
let column = block.closest('.epr-col-right');
|
||
if (!column) {
|
||
return;
|
||
}
|
||
|
||
let btnToggle = block.querySelector('.epr-block-toggle');
|
||
if (!block.classList.contains('is-collapsed')) {
|
||
if (btnToggle) {
|
||
bibToggleCollapsibleBlock(block, btnToggle);
|
||
}
|
||
return;
|
||
}
|
||
|
||
column.querySelectorAll('.epr-block-gestion, .epr-block-assign').forEach(function (otherBlock) {
|
||
if (otherBlock === block || otherBlock.classList.contains('is-collapsed')) {
|
||
return;
|
||
}
|
||
|
||
let otherToggle = otherBlock.querySelector('.epr-block-toggle');
|
||
if (otherToggle) {
|
||
bibToggleCollapsibleBlock(otherBlock, otherToggle);
|
||
}
|
||
});
|
||
|
||
if (btnToggle) {
|
||
bibToggleCollapsibleBlock(block, btnToggle);
|
||
}
|
||
}
|
||
|
||
function bibCollapseGlobalBatchSection(section) {
|
||
if (!section || section.classList.contains('is-collapsed')) {
|
||
return;
|
||
}
|
||
|
||
var btnToggle = section.querySelector('.epr-block-toggle');
|
||
if (btnToggle) {
|
||
bibToggleCollapsibleBlock(section, btnToggle);
|
||
} else {
|
||
section.classList.add('is-collapsed');
|
||
var hdr = section.querySelector('.bib-global-batch__section-header');
|
||
if (hdr) {
|
||
hdr.setAttribute('aria-expanded', 'false');
|
||
}
|
||
}
|
||
}
|
||
|
||
function bibToggleGlobalBatchSection(section, btnToggle) {
|
||
if (!section || !btnToggle) {
|
||
return;
|
||
}
|
||
|
||
var willExpand = section.classList.contains('is-collapsed');
|
||
var root = bibGetGlobalBatchBody();
|
||
|
||
if (willExpand && root) {
|
||
root.querySelectorAll('.bib-global-batch__section').forEach(function (other) {
|
||
if (other !== section) {
|
||
bibCollapseGlobalBatchSection(other);
|
||
}
|
||
});
|
||
}
|
||
|
||
bibToggleCollapsibleBlock(section, btnToggle);
|
||
|
||
if (!section.classList.contains('is-collapsed')) {
|
||
if (section.classList.contains('bib-global-batch--existing')) {
|
||
updateGlobalBatchAnalysis();
|
||
} else if (section.classList.contains('bib-global-batch--generated')) {
|
||
updateGlobalBatchGeneratedAnalysis();
|
||
}
|
||
}
|
||
}
|
||
|
||
moduleBib.addEventListener('click', function (e) {
|
||
if (e.target.closest('.btn-aide-bib, .bib-aide-trigger, .btn-aide-trad, .btn-doc-trigger, .btn-admin-doc, .btn-trad-admin, .ms1-trad-link')) {
|
||
return;
|
||
}
|
||
|
||
let raceSummary = e.target.closest('.bib-race-summary');
|
||
if (raceSummary && moduleBib.contains(raceSummary)) {
|
||
if (e.target.closest('a, input, select, textarea, button:not(.bib-race-toggle)')) {
|
||
return;
|
||
}
|
||
e.preventDefault();
|
||
bibToggleRaceRow(raceSummary.closest('.epr-row'));
|
||
return;
|
||
}
|
||
|
||
let raceBlockHeader = e.target.closest(
|
||
'.epr-block-gestion > .epr-header--collapsible, .epr-block-assign > .epr-header--collapsible'
|
||
);
|
||
if (raceBlockHeader && moduleBib.contains(raceBlockHeader)) {
|
||
e.preventDefault();
|
||
bibActivateRaceDetailBlock(raceBlockHeader.closest('.epr-block'));
|
||
return;
|
||
}
|
||
|
||
let anomalyHdr = e.target.closest('.bib-anomaly-block-header');
|
||
if (anomalyHdr && moduleBib.contains(anomalyHdr) && !e.target.closest('.epr-block-toggle')) {
|
||
e.preventDefault();
|
||
let anomalyBlock = anomalyHdr.closest('.bib-anomaly-block');
|
||
let anomalyBtn = anomalyHdr.querySelector('.epr-block-toggle');
|
||
if (anomalyBlock && anomalyBtn) {
|
||
bibToggleCollapsibleBlock(anomalyBlock, anomalyBtn);
|
||
}
|
||
return;
|
||
}
|
||
|
||
let globalBatchHdr = e.target.closest('.bib-global-batch__section-header');
|
||
if (globalBatchHdr && moduleBib.contains(globalBatchHdr)
|
||
&& !e.target.closest('.epr-block-toggle, .btn-aide-bib, .bib-aide-trigger, .btn-aide-trad, .btn-trad-admin')) {
|
||
e.preventDefault();
|
||
let globalBatchSection = globalBatchHdr.closest('.bib-global-batch__section');
|
||
let globalBatchBtn = globalBatchHdr.querySelector('.epr-block-toggle');
|
||
if (globalBatchSection && globalBatchBtn) {
|
||
bibToggleGlobalBatchSection(globalBatchSection, globalBatchBtn);
|
||
}
|
||
return;
|
||
}
|
||
|
||
let btnToggle = e.target.closest('.epr-block-toggle');
|
||
if (!btnToggle || !moduleBib.contains(btnToggle)) {
|
||
return;
|
||
}
|
||
|
||
let globalBatchSection = btnToggle.closest('.bib-global-batch__section');
|
||
if (globalBatchSection && moduleBib.contains(globalBatchSection)) {
|
||
e.preventDefault();
|
||
bibToggleGlobalBatchSection(globalBatchSection, btnToggle);
|
||
return;
|
||
}
|
||
|
||
let anomalyBlock = btnToggle.closest('.bib-anomaly-block');
|
||
if (anomalyBlock) {
|
||
e.preventDefault();
|
||
bibToggleCollapsibleBlock(anomalyBlock, btnToggle);
|
||
return;
|
||
}
|
||
|
||
let block = btnToggle.closest('.epr-block');
|
||
if (!block || block.closest('#bib-tool-store')) {
|
||
return;
|
||
}
|
||
bibToggleCollapsibleBlock(block, btnToggle);
|
||
|
||
// MSIN-4424 — Sommaire quantités : chargement à la première ouverture (accordéon épreuve).
|
||
if (!block.classList.contains('is-collapsed') && block.id === 'bib-qty-summary-panel'
|
||
&& block.getAttribute('data-bib-qty-summary-deferred') === '1') {
|
||
refreshBibQtySummaryPanel();
|
||
}
|
||
|
||
// MSIN-4433 — Impression PDF : chargement à la première ouverture (accordéon épreuve).
|
||
if (!block.classList.contains('is-collapsed') && block.id === 'bib-dist-print-panel'
|
||
&& block.getAttribute('data-bib-dist-print-deferred') === '1') {
|
||
refreshBibDistPrintPanel();
|
||
}
|
||
});
|
||
|
||
moduleBib.addEventListener('keydown', function (e) {
|
||
if (e.key !== 'Enter' && e.key !== ' ') {
|
||
return;
|
||
}
|
||
|
||
let raceSummary = e.target.closest('.bib-race-summary');
|
||
if (raceSummary && moduleBib.contains(raceSummary)) {
|
||
if (e.target !== raceSummary && !e.target.closest('.bib-race-toggle')) {
|
||
return;
|
||
}
|
||
e.preventDefault();
|
||
bibToggleRaceRow(raceSummary.closest('.epr-row'));
|
||
return;
|
||
}
|
||
|
||
let globalBatchHdr = e.target.closest('.bib-global-batch__section-header');
|
||
if (globalBatchHdr && moduleBib.contains(globalBatchHdr)) {
|
||
e.preventDefault();
|
||
let globalBatchSection = globalBatchHdr.closest('.bib-global-batch__section');
|
||
let globalBatchBtn = globalBatchHdr.querySelector('.epr-block-toggle');
|
||
if (globalBatchSection && globalBatchBtn) {
|
||
bibToggleGlobalBatchSection(globalBatchSection, globalBatchBtn);
|
||
}
|
||
return;
|
||
}
|
||
|
||
let anomalyHdr = e.target.closest('.bib-anomaly-block-header');
|
||
if (!anomalyHdr || !moduleBib.contains(anomalyHdr)) {
|
||
return;
|
||
}
|
||
e.preventDefault();
|
||
let anomalyBlock = anomalyHdr.closest('.bib-anomaly-block');
|
||
let anomalyBtn = anomalyHdr.querySelector('.epr-block-toggle');
|
||
if (anomalyBlock && anomalyBtn) {
|
||
bibToggleCollapsibleBlock(anomalyBlock, anomalyBtn);
|
||
}
|
||
});
|
||
|
||
// ============================================================
|
||
// MSIN-4379 — Tippy.js (module #module-bib uniquement)
|
||
// info_texte → data-tippy-content (tip court)
|
||
// info_aide → data-tippy-content sur .btn-aide-bib (pop-up long)
|
||
// Ré-init après chaque refresh AJAX des séquences.
|
||
// ============================================================
|
||
|
||
function getBibContainer(row) {
|
||
if (!row) return null;
|
||
return row.querySelector('.epr-block-assign .epr-table.bib-container')
|
||
|| row.querySelector('.epr-table.bib-container')
|
||
|| row.querySelector('.epr-block-assign .bib-container')
|
||
|| row.querySelector('.bib-container');
|
||
}
|
||
|
||
function bibTippyEscapeHtml(str) {
|
||
return String(str)
|
||
.replace(/&/g, '&')
|
||
.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);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/** MSIN-4530 — Comme bibSetVisible, mais pour tous les matches (ex. 4 niveaux de tri). */
|
||
function bibSetVisibleAll(selector, show, row) {
|
||
let root = row || moduleBib;
|
||
if (!root || !selector) {
|
||
return;
|
||
}
|
||
root.querySelectorAll(selector).forEach(function (el) {
|
||
el.classList.toggle('bib-ui-hidden', !show);
|
||
});
|
||
}
|
||
|
||
function bibRowModes(row) {
|
||
return {
|
||
batch: row.classList.contains('batch-mode'),
|
||
auto: row.classList.contains('auto-mode'),
|
||
reset: row.classList.contains('reset-mode'),
|
||
};
|
||
}
|
||
|
||
function bibHasSavedSequences(row) {
|
||
return Array.from(row.querySelectorAll('.bib-range[data-id]')).some(function (line) {
|
||
return parseInt(line.getAttribute('data-id') || '0', 10) > 0;
|
||
});
|
||
}
|
||
|
||
function bibCountSelectedRanges(row) {
|
||
// MSIN-4526 — Ignorer les cases masquées (autre mode).
|
||
return Array.from(row.querySelectorAll('.batch-select-range:checked')).filter(function (cb) {
|
||
let wrap = cb.closest('.batch-checkbox');
|
||
return wrap && !wrap.classList.contains('bib-ui-hidden');
|
||
}).length;
|
||
}
|
||
|
||
/** MSIN-4436 — Développe un bloc repliable #module-bib. */
|
||
function bibExpandBlock(block) {
|
||
if (!block || !block.classList.contains('is-collapsed')) {
|
||
return;
|
||
}
|
||
|
||
block.classList.remove('is-collapsed');
|
||
let btn = block.querySelector('.epr-block-toggle');
|
||
if (btn) {
|
||
btn.setAttribute('aria-expanded', 'true');
|
||
let label = btn.getAttribute('data-label-collapse') || '';
|
||
if (label) {
|
||
btn.setAttribute('aria-label', label);
|
||
btn.setAttribute('title', label);
|
||
}
|
||
let icon = btn.querySelector('.fa');
|
||
if (icon) {
|
||
icon.classList.add('fa-chevron-up');
|
||
icon.classList.remove('fa-chevron-down');
|
||
}
|
||
}
|
||
}
|
||
|
||
let bibFocusApplied = false;
|
||
|
||
/** MSIN-4436 — Retour depuis fiche inscription : rouvrir le panneau ciblé. */
|
||
function bibApplyFocusFromUrlOnce() {
|
||
if (bibFocusApplied) {
|
||
return;
|
||
}
|
||
|
||
let focus = new URLSearchParams(window.location.search).get('bib_focus');
|
||
if (!focus) {
|
||
return;
|
||
}
|
||
|
||
bibFocusApplied = true;
|
||
|
||
let focusMap = {
|
||
anomalies: 'anomalies',
|
||
qty_summary: 'qty_summary',
|
||
dist_print: 'dist_print',
|
||
event_config: 'event_config'
|
||
};
|
||
|
||
let toolId = focusMap[focus];
|
||
if (!toolId) {
|
||
return;
|
||
}
|
||
|
||
bibSetWorkspace(bibWorkspaceForTool(toolId), { keepTool: true });
|
||
bibOpenTool(toolId).then(function () {
|
||
let detail = document.getElementById('bib-tool-detail');
|
||
if (detail) {
|
||
detail.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||
}
|
||
});
|
||
}
|
||
|
||
/** MSIN-4379 — Rafraîchit le dashboard anomalies (chien de garde). */
|
||
function refreshBibAnomaliesPanel() {
|
||
let mount = document.getElementById('bib-anomalies-mount');
|
||
if (!mount || !moduleBib) {
|
||
return Promise.resolve();
|
||
}
|
||
|
||
let eveId = moduleBib.dataset.eveId || '';
|
||
if (!eveId) {
|
||
return Promise.resolve();
|
||
}
|
||
|
||
return bibFetch('/ajax_bib_range.php', {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/x-www-form-urlencoded'
|
||
},
|
||
body: 'action=anomalies&eve_id=' + encodeURIComponent(eveId) + bibAjaxLangSuffix()
|
||
}, { loader: false })
|
||
.then(function (res) { return res.json(); })
|
||
.then(function (data) {
|
||
if (!data.success || !data.html) {
|
||
return;
|
||
}
|
||
|
||
let blnWasActive = bibActiveTool === 'anomalies';
|
||
if (blnWasActive) {
|
||
bibRestoreToolContent('anomalies');
|
||
}
|
||
bibInvalidateToolSlot('anomalies');
|
||
mount.innerHTML = data.html;
|
||
initModuleBibTippy(mount);
|
||
bibSyncToolNavBadges('anomalies');
|
||
bibRemountActiveToolAfterRefresh('anomalies');
|
||
});
|
||
}
|
||
|
||
/** MSIN-4433 — Rafraîchit le panneau impression PDF. */
|
||
function refreshBibDistPrintPanel() {
|
||
let mount = document.getElementById('bib-dist-print-mount');
|
||
if (!mount || !moduleBib) {
|
||
return Promise.resolve();
|
||
}
|
||
|
||
let panel = document.getElementById('bib-dist-print-panel');
|
||
let blnDeferred = panel && panel.getAttribute('data-bib-dist-print-deferred') === '1';
|
||
let blnLoaded = panel && panel.getAttribute('data-bib-dist-print-loaded') === '1';
|
||
if (!blnDeferred && !blnLoaded) {
|
||
return Promise.resolve();
|
||
}
|
||
|
||
let eveId = moduleBib.dataset.eveId || '';
|
||
if (!eveId) {
|
||
return Promise.resolve();
|
||
}
|
||
|
||
let blnWasActive = bibActiveTool === 'dist_print';
|
||
|
||
return bibFetch('/ajax_bib_range.php', {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/x-www-form-urlencoded'
|
||
},
|
||
body: 'action=dist_print_panel&eve_id=' + encodeURIComponent(eveId) + bibAjaxLangSuffix()
|
||
}, { loader: true })
|
||
.then(function (res) { return res.json(); })
|
||
.then(function (data) {
|
||
if (!data.success || !data.html) {
|
||
return;
|
||
}
|
||
if (blnWasActive) {
|
||
bibRestoreToolContent('dist_print');
|
||
}
|
||
bibInvalidateToolSlot('dist_print');
|
||
mount.innerHTML = data.html;
|
||
initModuleBibTippy(mount);
|
||
initBibDistPrintPanel(mount);
|
||
bibRemountActiveToolAfterRefresh('dist_print');
|
||
});
|
||
}
|
||
|
||
/** MSIN-4433 / MSIN-4512 — mockup A via MS1UiChooser + SortableJS. */
|
||
function initBibDistPrintPanel(root) {
|
||
root = root || document;
|
||
let panel = root.querySelector ? root.querySelector('#bib-dist-print-panel') : null;
|
||
if (!panel) {
|
||
panel = document.getElementById('bib-dist-print-panel');
|
||
}
|
||
if (!panel || panel.getAttribute('data-bib-dist-print-init') === '1') {
|
||
return;
|
||
}
|
||
panel.setAttribute('data-bib-dist-print-init', '1');
|
||
|
||
let chooser = panel.querySelector('.ms1-ui-chooser[data-ms1-ui-screen="bib-dist-print"]')
|
||
|| panel.querySelector('.ms1-ui-chooser');
|
||
if (!chooser || !window.MS1UiChooser || typeof window.MS1UiChooser.init !== 'function') {
|
||
return;
|
||
}
|
||
|
||
function bibDistPrintBudget() {
|
||
let radio = chooser.querySelector('.bib-dist-print-orient-radio:checked, .ms1-ui-chooser-radio:checked');
|
||
let orient = radio ? String(radio.value || 'P') : 'P';
|
||
let budget = parseInt(
|
||
chooser.getAttribute(orient === 'L' ? 'data-budget-l' : 'data-budget-p')
|
||
|| panel.getAttribute(orient === 'L' ? 'data-budget-l' : 'data-budget-p')
|
||
|| '0',
|
||
10
|
||
);
|
||
return budget > 0 ? budget : 100;
|
||
}
|
||
|
||
window.MS1UiChooser.init(chooser, {
|
||
getBudget: bibDistPrintBudget,
|
||
radioSelector: '.bib-dist-print-orient-radio, .ms1-ui-chooser-radio',
|
||
labelRemove: panel.getAttribute('data-label-remove') || '',
|
||
fitUsedTpl: panel.getAttribute('data-fit-used-tpl') || '',
|
||
fitOver: panel.getAttribute('data-fit-over') || '',
|
||
fitFull: panel.getAttribute('data-fit-full') || ''
|
||
});
|
||
|
||
let form = panel.querySelector('.bib-dist-print-form');
|
||
if (form) {
|
||
form.addEventListener('submit', function () {
|
||
window.setTimeout(function () {
|
||
refreshBibDistPrintPanel();
|
||
}, 1500);
|
||
});
|
||
}
|
||
}
|
||
|
||
/** MSIN-4424 — Rafraîchit le sommaire des quantités (si déjà chargé ou ouverture). */
|
||
function refreshBibQtySummaryPanel() {
|
||
let mount = document.getElementById('bib-qty-summary-mount');
|
||
if (!mount || !moduleBib) {
|
||
return Promise.resolve();
|
||
}
|
||
|
||
let panel = document.getElementById('bib-qty-summary-panel');
|
||
let blnDeferred = panel && panel.getAttribute('data-bib-qty-summary-deferred') === '1';
|
||
let blnLoaded = panel && panel.getAttribute('data-bib-qty-summary-loaded') === '1';
|
||
if (!blnDeferred && !blnLoaded) {
|
||
return Promise.resolve();
|
||
}
|
||
|
||
let eveId = moduleBib.dataset.eveId || '';
|
||
if (!eveId) {
|
||
return Promise.resolve();
|
||
}
|
||
|
||
let blnWasActive = bibActiveTool === 'qty_summary';
|
||
|
||
return bibFetch('/ajax_bib_range.php', {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/x-www-form-urlencoded'
|
||
},
|
||
body: 'action=qty_summary&eve_id=' + encodeURIComponent(eveId) + bibAjaxLangSuffix()
|
||
}, { loader: true })
|
||
.then(function (res) { return res.json(); })
|
||
.then(function (data) {
|
||
if (!data.success || !data.html) {
|
||
return;
|
||
}
|
||
if (blnWasActive) {
|
||
bibRestoreToolContent('qty_summary');
|
||
}
|
||
bibInvalidateToolSlot('qty_summary');
|
||
mount.innerHTML = data.html;
|
||
initModuleBibTippy(mount);
|
||
bibSyncToolNavBadges('qty_summary');
|
||
bibRemountActiveToolAfterRefresh('qty_summary');
|
||
});
|
||
}
|
||
|
||
function bibQtySummaryShouldRefresh() {
|
||
let panel = document.getElementById('bib-qty-summary-panel');
|
||
return panel && panel.getAttribute('data-bib-qty-summary-loaded') === '1';
|
||
}
|
||
|
||
function setBibContainerHtml(row, html, opts) {
|
||
opts = opts || {};
|
||
let container = getBibContainer(row);
|
||
if (!container) return null;
|
||
// renderBibRanges renvoie un bloc .epr-table.bib-container complet.
|
||
if (html.indexOf('bib-container') !== -1) {
|
||
container.outerHTML = html;
|
||
container = getBibContainer(row);
|
||
} else {
|
||
container.innerHTML = html;
|
||
}
|
||
// MSIN-4446 — Pastille « N séquence(s) » hors du conteneur AJAX.
|
||
if (opts.summaryHtml != null) {
|
||
let summaries = row.querySelector('.epr-block-assign .epr-header-summaries');
|
||
if (summaries) {
|
||
summaries.innerHTML = opts.summaryHtml;
|
||
}
|
||
}
|
||
if (typeof opts.seqCount !== 'undefined') {
|
||
let summaryRanges = row.querySelector('.bib-race-summary-ranges');
|
||
if (summaryRanges) {
|
||
summaryRanges.textContent = parseInt(opts.seqCount, 10) || 0;
|
||
}
|
||
let productionRanges = moduleBib.querySelector(
|
||
'.bib-production-category[data-epr-id="' + row.dataset.eprId + '"] .bib-production-range-count'
|
||
);
|
||
if (productionRanges) {
|
||
productionRanges.textContent = parseInt(opts.seqCount, 10) || 0;
|
||
}
|
||
bibSyncRaceSummaryStatus(row);
|
||
}
|
||
if (typeof opts.autoActive !== 'undefined') {
|
||
let blnAuto = !!opts.autoActive && opts.autoActive !== '0' && opts.autoActive !== 0;
|
||
row.dataset.autoActive = blnAuto ? '1' : '0';
|
||
row.classList.toggle('auto-enabled', blnAuto);
|
||
}
|
||
if (container) {
|
||
initModuleBibTippy(row);
|
||
initBibRangeRows(container);
|
||
}
|
||
// MSIN-4534 — skipSync : différer syncBibUiState jusqu'aux stats finales (évite menus en retard).
|
||
if (!opts.skipSync) {
|
||
syncBibUiState(row);
|
||
}
|
||
if (!opts.skipAnomalies) {
|
||
refreshBibAnomaliesPanel();
|
||
}
|
||
if (!opts.skipQtySummary && bibQtySummaryShouldRefresh()) {
|
||
refreshBibQtySummaryPanel();
|
||
}
|
||
return container;
|
||
}
|
||
|
||
/** MSIN-4446 — Applique html + pastille résumé depuis une réponse AJAX ranges. */
|
||
function setBibContainerFromAjax(row, data, opts) {
|
||
opts = opts || {};
|
||
if (data && data.summary_html != null) {
|
||
opts.summaryHtml = data.summary_html;
|
||
}
|
||
if (data && typeof data.seq_count !== 'undefined') {
|
||
opts.seqCount = data.seq_count;
|
||
}
|
||
if (data && typeof data.auto_active !== 'undefined') {
|
||
opts.autoActive = data.auto_active;
|
||
}
|
||
return setBibContainerHtml(row, data.html, opts);
|
||
}
|
||
|
||
// MSIN-4429 — Séquence : Début puis Qté ou Fin (pilote / calculé).
|
||
function bibRangeParseInt(val) {
|
||
var n = parseInt(String(val || '').trim(), 10);
|
||
return isNaN(n) ? 0 : n;
|
||
}
|
||
|
||
function bibRangeGetFields(row) {
|
||
if (!row) return null;
|
||
return {
|
||
start: row.querySelector('.bib-start'),
|
||
qty: row.querySelector('.bib-qty'),
|
||
end: row.querySelector('.bib-end')
|
||
};
|
||
}
|
||
|
||
function bibRangeGetErrorEl(row) {
|
||
var el = row && row.nextElementSibling;
|
||
if (el && el.classList.contains('bib-error')) {
|
||
return el;
|
||
}
|
||
return null;
|
||
}
|
||
|
||
function bibRangeClearRangeError(row) {
|
||
var errEl = bibRangeGetErrorEl(row);
|
||
if (!errEl) return;
|
||
|
||
var msg = errEl.querySelector('.bib-range-validate-msg');
|
||
if (msg) {
|
||
msg.remove();
|
||
}
|
||
|
||
if (!errEl.querySelector('div:not(.bib-range-validate-msg)') && !errEl.textContent.trim()) {
|
||
errEl.style.display = 'none';
|
||
}
|
||
}
|
||
|
||
function bibRangeClearFieldClasses(row) {
|
||
var fields = bibRangeGetFields(row);
|
||
if (!fields) return;
|
||
[fields.start, fields.qty, fields.end].forEach(function (el) {
|
||
if (!el) return;
|
||
el.classList.remove('bib-field--idle', 'bib-field--pick', 'bib-field--calc', 'bib-field--active');
|
||
});
|
||
}
|
||
|
||
function bibRangeClearValidationUi(row) {
|
||
var fields = bibRangeGetFields(row);
|
||
if (!fields) return;
|
||
|
||
[fields.start, fields.qty, fields.end].forEach(function (el) {
|
||
if (el) {
|
||
el.classList.remove('bib-field--invalid');
|
||
}
|
||
});
|
||
|
||
bibRangeClearRangeError(row);
|
||
}
|
||
|
||
/** MSIN-4429 — Validation différée (blur / OK), pas pendant la frappe. */
|
||
function bibRangeValidate(row) {
|
||
var fields = bibRangeGetFields(row);
|
||
if (!fields) return null;
|
||
|
||
var start = bibRangeParseInt(fields.start && fields.start.value);
|
||
if (start <= 0) {
|
||
return null;
|
||
}
|
||
|
||
var pilot = row.dataset.rangePilot || '';
|
||
if (!pilot) {
|
||
return null;
|
||
}
|
||
|
||
if (pilot === 'end') {
|
||
var strEnd = String(fields.end && fields.end.value || '').trim();
|
||
if (strEnd === '') {
|
||
return null;
|
||
}
|
||
var end = bibRangeParseInt(strEnd);
|
||
if (end <= 0) {
|
||
return { key: 'incomplete', field: 'end' };
|
||
}
|
||
if (end < start) {
|
||
return { key: 'invalidEnd', field: 'end', start: start };
|
||
}
|
||
}
|
||
|
||
if (pilot === 'qty') {
|
||
var strQty = String(fields.qty && fields.qty.value || '').trim();
|
||
if (strQty === '') {
|
||
return null;
|
||
}
|
||
var qty = bibRangeParseInt(strQty);
|
||
if (qty <= 0) {
|
||
return { key: 'invalidQty', field: 'qty' };
|
||
}
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
function bibRangeValidationMessage(validation) {
|
||
if (!validation) {
|
||
return '';
|
||
}
|
||
if (validation.key === 'invalidEnd') {
|
||
return bibJsFmt('jsRangeInvalidEnd', validation.start);
|
||
}
|
||
if (validation.key === 'invalidQty') {
|
||
return bibJs('jsRangeInvalidQty');
|
||
}
|
||
if (validation.key === 'incomplete') {
|
||
return bibJs('jsRangeIncomplete') || bibJs('jsFieldsRequired');
|
||
}
|
||
return bibJs('jsRangeInvalid') || bibJs('jsFieldsRequired');
|
||
}
|
||
|
||
function bibRangeShowValidation(row, validation) {
|
||
var fields = bibRangeGetFields(row);
|
||
if (!fields) {
|
||
return;
|
||
}
|
||
|
||
bibRangeClearValidationUi(row);
|
||
|
||
if (!validation) {
|
||
return;
|
||
}
|
||
|
||
var target = validation.field === 'qty' ? fields.qty : fields.end;
|
||
if (target) {
|
||
target.classList.add('bib-field--invalid');
|
||
}
|
||
|
||
var errEl = bibRangeGetErrorEl(row);
|
||
if (!errEl) {
|
||
return;
|
||
}
|
||
|
||
var msgEl = errEl.querySelector('.bib-range-validate-msg');
|
||
if (!msgEl) {
|
||
msgEl = document.createElement('div');
|
||
msgEl.className = 'bib-range-validate-msg';
|
||
errEl.insertBefore(msgEl, errEl.firstChild);
|
||
}
|
||
msgEl.textContent = bibRangeValidationMessage(validation);
|
||
errEl.style.display = 'block';
|
||
}
|
||
|
||
function bibRangeValidateOnBlur(row) {
|
||
applyBibRangeFieldState(row);
|
||
bibRangeShowValidation(row, bibRangeValidate(row));
|
||
}
|
||
|
||
function applyBibRangeFieldState(row) {
|
||
var fields = bibRangeGetFields(row);
|
||
if (!fields || !fields.start || !fields.qty || !fields.end) return;
|
||
|
||
if (row.dataset.locked === '1') {
|
||
bibRangeClearFieldClasses(row);
|
||
return;
|
||
}
|
||
|
||
var start = bibRangeParseInt(fields.start.value);
|
||
var pilot = row.dataset.rangePilot || '';
|
||
|
||
bibRangeClearFieldClasses(row);
|
||
|
||
if (start <= 0) {
|
||
fields.qty.classList.add('bib-field--idle');
|
||
fields.end.classList.add('bib-field--idle');
|
||
fields.qty.readOnly = true;
|
||
fields.end.readOnly = true;
|
||
fields.qty.value = '';
|
||
fields.end.value = '';
|
||
row.dataset.rangePilot = '';
|
||
return;
|
||
}
|
||
|
||
if (!pilot) {
|
||
fields.qty.classList.add('bib-field--pick');
|
||
fields.end.classList.add('bib-field--pick');
|
||
fields.qty.readOnly = true;
|
||
fields.end.readOnly = true;
|
||
return;
|
||
}
|
||
|
||
if (pilot === 'qty') {
|
||
var qty = bibRangeParseInt(fields.qty.value);
|
||
fields.qty.classList.add('bib-field--active');
|
||
fields.end.classList.add('bib-field--calc');
|
||
fields.qty.readOnly = false;
|
||
fields.end.readOnly = true;
|
||
if (qty > 0) {
|
||
fields.end.value = String(start + qty - 1);
|
||
} else {
|
||
fields.end.value = '';
|
||
}
|
||
} else if (pilot === 'end') {
|
||
var end = bibRangeParseInt(fields.end.value);
|
||
fields.end.classList.add('bib-field--active');
|
||
fields.qty.classList.add('bib-field--calc');
|
||
fields.end.readOnly = false;
|
||
fields.qty.readOnly = true;
|
||
if (end >= start) {
|
||
fields.qty.value = String(end - start + 1);
|
||
} else {
|
||
fields.qty.value = '';
|
||
}
|
||
}
|
||
}
|
||
|
||
function onBibRangeFieldPick(row, pilot) {
|
||
if (!row || row.dataset.locked === '1') return;
|
||
|
||
var fields = bibRangeGetFields(row);
|
||
if (!fields || !fields.start) return;
|
||
|
||
if (bibRangeParseInt(fields.start.value) <= 0) {
|
||
fields.start.focus();
|
||
return;
|
||
}
|
||
|
||
row.dataset.rangePilot = pilot;
|
||
applyBibRangeFieldState(row);
|
||
|
||
var target = pilot === 'qty' ? fields.qty : fields.end;
|
||
if (target) {
|
||
target.focus();
|
||
target.select();
|
||
}
|
||
}
|
||
|
||
function onBibRangeStartChange(row) {
|
||
var fields = bibRangeGetFields(row);
|
||
if (!fields || !fields.start) return;
|
||
|
||
var start = bibRangeParseInt(fields.start.value);
|
||
var lastStart = bibRangeParseInt(row.dataset.rangeLastStart || '0');
|
||
|
||
if (start !== lastStart && !row.dataset.rangePilot) {
|
||
fields.qty.value = '';
|
||
fields.end.value = '';
|
||
row.dataset.hasValues = '0';
|
||
}
|
||
|
||
row.dataset.rangeLastStart = String(start);
|
||
|
||
if (start <= 0) {
|
||
row.dataset.rangePilot = '';
|
||
}
|
||
|
||
applyBibRangeFieldState(row);
|
||
}
|
||
|
||
function bindBibRangeRow(row) {
|
||
if (!row || row.dataset.bibRangeBound === '1') return;
|
||
row.dataset.bibRangeBound = '1';
|
||
|
||
var fields = bibRangeGetFields(row);
|
||
if (!fields || !fields.start || !fields.qty || !fields.end) return;
|
||
|
||
row.dataset.rangeLastStart = String(bibRangeParseInt(fields.start.value));
|
||
|
||
fields.start.addEventListener('input', function () {
|
||
bibRangeClearValidationUi(row);
|
||
onBibRangeStartChange(row);
|
||
});
|
||
|
||
fields.qty.addEventListener('input', function () {
|
||
bibRangeClearValidationUi(row);
|
||
row.dataset.rangePilot = 'qty';
|
||
applyBibRangeFieldState(row);
|
||
});
|
||
|
||
fields.end.addEventListener('input', function () {
|
||
bibRangeClearValidationUi(row);
|
||
row.dataset.rangePilot = 'end';
|
||
applyBibRangeFieldState(row);
|
||
});
|
||
|
||
fields.start.addEventListener('blur', function () {
|
||
bibRangeValidateOnBlur(row);
|
||
});
|
||
|
||
fields.qty.addEventListener('blur', function () {
|
||
bibRangeValidateOnBlur(row);
|
||
});
|
||
|
||
fields.end.addEventListener('blur', function () {
|
||
bibRangeValidateOnBlur(row);
|
||
});
|
||
|
||
fields.qty.addEventListener('click', function () {
|
||
onBibRangeFieldPick(row, 'qty');
|
||
});
|
||
|
||
fields.end.addEventListener('click', function () {
|
||
onBibRangeFieldPick(row, 'end');
|
||
});
|
||
|
||
fields.qty.addEventListener('focus', function () {
|
||
onBibRangeFieldPick(row, 'qty');
|
||
});
|
||
|
||
fields.end.addEventListener('focus', function () {
|
||
onBibRangeFieldPick(row, 'end');
|
||
});
|
||
|
||
applyBibRangeFieldState(row);
|
||
|
||
if (row.dataset.id === '0' && !fields.start.value) {
|
||
fields.start.focus();
|
||
}
|
||
}
|
||
|
||
function initBibRangeRows(root) {
|
||
if (!root) return;
|
||
root.querySelectorAll('.bib-range').forEach(bindBibRangeRow);
|
||
}
|
||
|
||
function bibCsrfToken() {
|
||
return moduleBib ? (moduleBib.dataset.csrfToken || '') : '';
|
||
}
|
||
|
||
initModuleBibTippy(moduleBib);
|
||
|
||
// MSIN-4515 — Après génération Excel + reload : reprendre l’espace Production.
|
||
try {
|
||
var storedWs = window.sessionStorage.getItem('ms1_bib_workspace') || '';
|
||
if (storedWs === 'production' || storedWs === 'operations'
|
||
|| storedWs === 'settings' || storedWs === 'preparation') {
|
||
window.sessionStorage.removeItem('ms1_bib_workspace');
|
||
bibSetWorkspace(storedWs);
|
||
}
|
||
} catch (errRestoreWs) { /* ignore */ }
|
||
initBibRangeRows(moduleBib);
|
||
|
||
// ============================================================
|
||
// MSIN-4379 — Étape 2 : assignation automatique (interface JS)
|
||
// Prochain tour : étape 6 (fxAssignAutoBibForParticipant), étape 7 (fxMajCommande).
|
||
// ============================================================
|
||
|
||
/** MSIN-4379 — Compte les séquences cochées et met à jour le texte d'aide. */
|
||
function updateAutoSelectionInfo(row) {
|
||
|
||
if (!row) return;
|
||
|
||
let count = row.querySelectorAll('.batch-select-range:checked').length;
|
||
let info = row.querySelector('.auto-info-text');
|
||
if (!info) return;
|
||
|
||
if (count === 0) {
|
||
info.textContent = bibJs('jsAutoSelectHint');
|
||
} else {
|
||
info.textContent = bibJsFmt('jsAutoSelectCount', count);
|
||
}
|
||
}
|
||
|
||
function syncAutoUiState(row, isActive) {
|
||
if (!row) return;
|
||
|
||
let btnAuto = row.querySelector('.btn-auto');
|
||
row.dataset.autoActive = isActive ? '1' : '0';
|
||
row.classList.toggle('auto-enabled', isActive);
|
||
|
||
if (btnAuto) {
|
||
btnAuto.textContent = isActive ? row.dataset.autoLabelConfig : row.dataset.autoLabel;
|
||
btnAuto.classList.toggle('btn-bib-auto--active', isActive);
|
||
let autoAide = bibQuery(row, '.epr-action-auto-group .epr-btn-aide-segment .bib-aide-trigger');
|
||
if (autoAide) {
|
||
autoAide.classList.add('btn-aide-tone-auto');
|
||
autoAide.classList.remove('btn-aide-tone-success', 'btn-aide-tone-secondary');
|
||
}
|
||
}
|
||
}
|
||
|
||
/** MSIN-4564 — Quitte batch ou reset (bouton Fermer en bas). */
|
||
function exitBatchOrResetMode(row) {
|
||
if (!row) return;
|
||
|
||
let isReset = row.classList.contains('reset-mode');
|
||
let container = row.querySelector('.bib-container');
|
||
|
||
if (isReset) {
|
||
row.classList.remove('reset-mode');
|
||
row.dataset.mode = '';
|
||
let btnReset = row.querySelector('.btn-reset');
|
||
if (btnReset) {
|
||
btnReset.textContent = row.dataset.resetLabel || btnReset.textContent;
|
||
}
|
||
} else {
|
||
row.classList.remove('batch-mode');
|
||
let btnBatch = row.querySelector('.btn-assign-batch');
|
||
if (btnBatch) {
|
||
btnBatch.textContent = row.dataset.batchLabel || btnBatch.textContent;
|
||
}
|
||
}
|
||
|
||
if (container) {
|
||
container.classList.remove('batch-mode');
|
||
}
|
||
|
||
row.querySelectorAll('.bib-start, .bib-qty, .bib-end').forEach(function (input) {
|
||
input.removeAttribute('readonly');
|
||
});
|
||
|
||
row.querySelectorAll('.batch-select-range').forEach(function (cb) {
|
||
cb.checked = false;
|
||
cb.disabled = false;
|
||
});
|
||
|
||
let goBtn = row.querySelector('.btn-go-batch');
|
||
if (goBtn) {
|
||
goBtn.textContent = row.dataset.goLabel || goBtn.textContent;
|
||
}
|
||
|
||
let info = row.querySelector('.epr-actions .batch-info-text');
|
||
if (info) {
|
||
info.textContent = '';
|
||
info.innerHTML = '';
|
||
}
|
||
|
||
bibApplyRangeInputLockState(row);
|
||
syncBibUiState(row);
|
||
}
|
||
|
||
/** MSIN-4379 — Quitte le mode édition auto sans sauver. MSIN-4526 — local, sans refresh_ranges. */
|
||
function exitAutoMode(row) {
|
||
|
||
if (!row) return;
|
||
|
||
row.classList.remove('auto-mode');
|
||
|
||
let container = row.querySelector('.bib-container');
|
||
if (container) {
|
||
container.classList.remove('batch-mode');
|
||
}
|
||
|
||
row.querySelectorAll('.bib-start, .bib-qty, .bib-end').forEach(input => {
|
||
input.removeAttribute('readonly');
|
||
});
|
||
|
||
row.querySelectorAll('.batch-select-range').forEach(function (cb) {
|
||
cb.checked = false;
|
||
});
|
||
|
||
bibApplyRangeInputLockState(row);
|
||
syncBibUiState(row);
|
||
}
|
||
|
||
/** MSIN-4379 — Ouvre le mode édition auto. MSIN-4526 — local, sans refresh_ranges. */
|
||
function enterAutoMode(row) {
|
||
|
||
if (!row) return;
|
||
|
||
if (row.classList.contains('batch-mode') || row.classList.contains('reset-mode')) {
|
||
return;
|
||
}
|
||
|
||
if (bibBlockAutoActivation(row)) {
|
||
return;
|
||
}
|
||
|
||
row.classList.add('auto-mode');
|
||
|
||
let container = row.querySelector('.bib-container');
|
||
if (container) {
|
||
container.classList.add('batch-mode');
|
||
}
|
||
|
||
row.querySelectorAll('.bib-start, .bib-qty, .bib-end').forEach(input => {
|
||
input.setAttribute('readonly', true);
|
||
});
|
||
|
||
bibSyncModeRangeCheckboxes(row, { precheckAuto: true });
|
||
updateAutoSelectionInfo(row);
|
||
syncBibUiState(row);
|
||
}
|
||
|
||
function bibSyncResetAllEprButton(row) {
|
||
if (!row) {
|
||
return;
|
||
}
|
||
|
||
let wrap = row.querySelector('.epr-identity-reset-all');
|
||
if (!wrap) {
|
||
return;
|
||
}
|
||
|
||
let avecBib = parseInt(bibQuery(row, '.bib-avec')?.textContent || '0', 10) || 0;
|
||
if (avecBib <= 0) {
|
||
wrap.classList.add('bib-ui-hidden');
|
||
return;
|
||
}
|
||
|
||
wrap.classList.remove('bib-ui-hidden');
|
||
|
||
let btn = wrap.querySelector('.btn-reset-all-epr');
|
||
if (!btn) {
|
||
return;
|
||
}
|
||
|
||
let hasAssignLock = row.querySelector('.btn-bib-commande-lock--assign') !== null;
|
||
btn.disabled = hasAssignLock || bibRowIsProductionLocked(row);
|
||
}
|
||
|
||
/**
|
||
* MSIN-4526 — Affiche/masque les cases séquence selon le mode, sans AJAX.
|
||
* Assign/auto : dispo > 0. Reset : utilisés > 0.
|
||
* @param {HTMLElement} row
|
||
* @param {{precheckAuto?: boolean}} [opts]
|
||
*/
|
||
function bibSyncModeRangeCheckboxes(row, opts) {
|
||
opts = opts || {};
|
||
if (!row) {
|
||
return;
|
||
}
|
||
|
||
let modes = bibRowModes(row);
|
||
let inPickFlow = modes.batch || modes.reset || modes.auto;
|
||
|
||
row.querySelectorAll('.bib-range.epr-line').forEach(function (line) {
|
||
let wrap = line.querySelector('.batch-checkbox');
|
||
let cb = line.querySelector('.batch-select-range');
|
||
if (!wrap || !cb) {
|
||
return;
|
||
}
|
||
|
||
// MSIN-4577 — Cases assign/reset : le cadenas commande ne masque pas l’assignation.
|
||
if (!inPickFlow) {
|
||
wrap.classList.add('bib-ui-hidden');
|
||
cb.checked = false;
|
||
return;
|
||
}
|
||
|
||
let used = parseInt((line.querySelector('.bib-used')?.textContent || '0'), 10) || 0;
|
||
let dispo = parseInt((line.querySelector('.bib-dispo')?.textContent || '0'), 10) || 0;
|
||
let show = modes.reset ? (used > 0) : (dispo > 0);
|
||
|
||
if (!show) {
|
||
wrap.classList.add('bib-ui-hidden');
|
||
cb.checked = false;
|
||
return;
|
||
}
|
||
|
||
wrap.classList.remove('bib-ui-hidden');
|
||
|
||
if (opts.precheckAuto && modes.auto && line.dataset.bibAuto === '1') {
|
||
cb.checked = true;
|
||
}
|
||
});
|
||
}
|
||
|
||
function syncBibUiState(row) {
|
||
if (!row) return;
|
||
|
||
let modes = bibRowModes(row);
|
||
let avecBib = parseInt(bibQuery(row, '.bib-avec')?.textContent || '0', 10) || 0;
|
||
let hasSequences = bibHasSavedSequences(row);
|
||
let hasSelection = bibCountSelectedRanges(row) > 0;
|
||
let inBatchFlow = modes.batch || modes.reset;
|
||
let inAutoFlow = modes.auto;
|
||
let inPickFlow = inBatchFlow || inAutoFlow;
|
||
|
||
row.querySelectorAll('.team-mode-box input[type="radio"]').forEach(function (radio) {
|
||
if (!radio.closest('.team-mode-option.disabled')) {
|
||
radio.disabled = avecBib > 0;
|
||
}
|
||
});
|
||
|
||
// MSIN-4564 — Pendant le flux, masquer les boutons méthode (Fermer / Annuler en bas).
|
||
let showResetBtn = hasSequences && avecBib > 0
|
||
&& !modes.auto && !modes.batch && !modes.reset;
|
||
bibSetVisible('.bib-assignment-methods', !inPickFlow, row);
|
||
bibSetVisible('.bib-advanced-actions', showResetBtn, row);
|
||
bibSetVisible('.epr-action-batch-group',
|
||
hasSequences && !modes.reset && !modes.auto && !modes.batch, row);
|
||
bibSetVisible('.epr-action-reset-group', showResetBtn, row);
|
||
bibSetVisible('.epr-action-auto-group',
|
||
hasSequences && !modes.reset && !modes.auto && !modes.batch, row);
|
||
|
||
if (hasSequences) {
|
||
syncAutoUiState(row, row.dataset.autoActive === '1');
|
||
}
|
||
|
||
bibSetVisible('.epr-add-range-row', !inPickFlow, row);
|
||
bibSetVisible('.batch-config-container', inBatchFlow, row);
|
||
bibSetVisible('.auto-config-container', inAutoFlow, row);
|
||
|
||
bibSyncModeRangeCheckboxes(row);
|
||
|
||
hasSelection = bibCountSelectedRanges(row) > 0;
|
||
|
||
let showPick = inPickFlow && !hasSelection;
|
||
let showBatchReady = inBatchFlow && hasSelection;
|
||
let showAutoReady = inAutoFlow && hasSelection;
|
||
bibSetVisible('.bib-seq-pick-prompt', showPick, row);
|
||
bibSetVisible('.batch-config-ready', showBatchReady, row);
|
||
bibSetVisible('.auto-config-ready', showAutoReady, row);
|
||
|
||
let bibContainer = getBibContainer(row);
|
||
if (bibContainer) {
|
||
bibContainer.classList.toggle('batch-awaiting-selection', showPick);
|
||
}
|
||
|
||
bibSetVisible('.epr-action-desactiver-group',
|
||
hasSequences && row.dataset.autoActive === '1' && inAutoFlow, row);
|
||
// MSIN-4564 — Annuler = auto seulement ; Fermer = batch / reset.
|
||
bibSetVisible('.epr-action-cancel-auto-group', inAutoFlow && hasSequences, row);
|
||
bibSetVisible('.epr-action-close-batch-group', inBatchFlow && hasSequences, row);
|
||
bibSetVisible('.epr-action-accept-auto-group', showAutoReady, row);
|
||
bibSetVisible('.epr-auto-info-group', showAutoReady, row);
|
||
bibSetVisible('.batch-reset-warning', showBatchReady && modes.reset, row);
|
||
// MSIN-4530 — Tous les wraps de tri (pas seulement le 1er via querySelector).
|
||
// MSIN-4530 — tous les niveaux (1–4) ; reset = aucun tri. Pas de repli partiel.
|
||
let showSorts = showBatchReady && !modes.reset;
|
||
bibSetVisibleAll('.epr-batch-order-wrap', showSorts, row);
|
||
bibSetVisible('.epr-action-sim-group', showSorts, row);
|
||
bibSetVisible('.epr-action-go-group', showBatchReady, row);
|
||
bibSyncResetAllEprButton(row);
|
||
}
|
||
|
||
function updateBatchAnalysis(row) {
|
||
|
||
if (!row) return;
|
||
|
||
let totalDispo = 0;
|
||
let totalReset = 0;
|
||
|
||
// =====================
|
||
// TOTAL DISPO
|
||
// Source officielle = PHP
|
||
// JS ne recalcule PAS les disponibilités.
|
||
// Il additionne seulement les valeurs affichées dans .bib-dispo.
|
||
// =====================
|
||
row.querySelectorAll('.batch-select-range:checked').forEach(cb => {
|
||
|
||
let line = cb.closest('.epr-line');
|
||
if (!line) return;
|
||
|
||
let usedDiv = line.querySelector('.bib-used');
|
||
let dispoDiv = line.querySelector('.bib-dispo');
|
||
|
||
let used = parseInt((usedDiv?.textContent || '0'), 10);
|
||
let dispo = parseInt((dispoDiv?.textContent || '0'), 10);
|
||
|
||
if (isNaN(used)) {
|
||
used = 0;
|
||
}
|
||
|
||
if (isNaN(dispo)) {
|
||
dispo = 0;
|
||
}
|
||
|
||
totalReset += used;
|
||
totalDispo += dispo;
|
||
});
|
||
|
||
bibFetch('/ajax_bib_range.php', {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/x-www-form-urlencoded'
|
||
},
|
||
body: 'action=batch_analysis&epr_id=' + encodeURIComponent(row.dataset.eprId) + bibAjaxLangSuffix()
|
||
}, { loader: false })
|
||
.then(res => res.json())
|
||
.then(data => {
|
||
|
||
if (!data.success) return;
|
||
|
||
bibSyncEprBibStats(row, data.info);
|
||
syncBibUiState(row);
|
||
let sansBib = bibRowPendingBibs(row);
|
||
let isResetMode = row.dataset.mode === 'reset';
|
||
let message = '';
|
||
|
||
if (isResetMode) {
|
||
|
||
if (totalReset === 0) {
|
||
message = bibJs('jsBatchNone');
|
||
} else {
|
||
message = bibJsFmt('jsBatchResetCount', totalReset);
|
||
}
|
||
|
||
} else {
|
||
|
||
if (totalDispo === 0) {
|
||
message = bibJs('jsBatchNone');
|
||
} else if (totalDispo < sansBib) {
|
||
message = bibJsFmt('jsBatchSummaryShort', totalDispo, sansBib, sansBib - totalDispo);
|
||
} else {
|
||
message = bibJsFmt('jsBatchSummaryOk', totalDispo, sansBib);
|
||
}
|
||
|
||
}
|
||
|
||
let info = row.querySelector('.epr-actions .batch-info-text');
|
||
if (info && bibCountSelectedRanges(row) > 0) {
|
||
info.textContent = message;
|
||
}
|
||
|
||
syncBibUiState(row);
|
||
});
|
||
}
|
||
|
||
// =====================
|
||
// BATCH CHECKBOX CHANGE (PROPRE)
|
||
// =====================
|
||
moduleBib.addEventListener('change', function (e) {
|
||
|
||
// =====================
|
||
// TEAM MODE
|
||
// =====================
|
||
let teamRadio = e.target.closest('.team-mode-box input[type="radio"]');
|
||
|
||
if (teamRadio) {
|
||
|
||
if (teamRadio.disabled) return;
|
||
|
||
let box = teamRadio.closest('.team-mode-box');
|
||
if (!box) return;
|
||
|
||
bibFetch('/ajax_bib_range.php', {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/x-www-form-urlencoded'
|
||
},
|
||
body:
|
||
'action=save_team_mode'
|
||
+ '&epr_id=' + encodeURIComponent(box.dataset.eprId)
|
||
+ '&team_mode=' + encodeURIComponent(teamRadio.value)
|
||
+ bibAjaxLangSuffix()
|
||
}, { loader: false })
|
||
.then(function (res) { return res.json(); })
|
||
.then(function (data) {
|
||
if (!data.success) {
|
||
alert(data.message || bibJs('jsErrGeneric'));
|
||
return;
|
||
}
|
||
|
||
let row = teamRadio.closest('.epr-row');
|
||
let summary = row ? row.querySelector('.bib-race-summary-team-mode') : null;
|
||
let optionLabel = teamRadio.closest('.team-mode-option');
|
||
let optionText = optionLabel ? optionLabel.querySelector('span') : null;
|
||
if (summary && optionText) {
|
||
summary.textContent = optionText.textContent.trim();
|
||
}
|
||
});
|
||
|
||
return;
|
||
}
|
||
|
||
let cb = e.target.closest('.batch-select-range');
|
||
if (!cb) return;
|
||
|
||
let row = cb.closest('.epr-row');
|
||
if (!row) return;
|
||
|
||
// MSIN-4379 — Mode auto : même sélection de séquences que le batch, sans GO/simulation.
|
||
if (row.classList.contains('auto-mode')) {
|
||
updateAutoSelectionInfo(row);
|
||
syncBibUiState(row);
|
||
return;
|
||
}
|
||
|
||
// MSIN-4526 — Plus de refresh_ranges à chaque coche (CTE trous + rebuild HTML).
|
||
let existing = document.querySelector('.epr-row-view');
|
||
if (existing) {
|
||
existing.remove();
|
||
}
|
||
updateBatchAnalysis(row);
|
||
syncBibUiState(row);
|
||
});
|
||
|
||
moduleBib.querySelectorAll('.epr-row').forEach(syncBibUiState);
|
||
|
||
moduleBib.addEventListener('click', function (e) {
|
||
|
||
let btnQteTotal = e.target.closest('.btn_qte_total');
|
||
if (btnQteTotal && moduleBib.contains(btnQteTotal)) {
|
||
e.preventDefault();
|
||
bibSaveQteTotal(btnQteTotal);
|
||
return;
|
||
}
|
||
|
||
let btnGotoAssign = e.target.closest('.bib-anomaly-goto-assign');
|
||
if (btnGotoAssign) {
|
||
e.preventDefault();
|
||
|
||
let eprId = btnGotoAssign.dataset.eprId;
|
||
if (!eprId) {
|
||
return;
|
||
}
|
||
|
||
let row = moduleBib.querySelector('.epr-row[data-epr-id="' + eprId + '"]');
|
||
if (row) {
|
||
row.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||
let btnView = row.querySelector('.btn-view-range[data-range-id="0"]');
|
||
if (btnView) {
|
||
btnView.click();
|
||
}
|
||
}
|
||
return;
|
||
}
|
||
|
||
let btnTrad = e.target.closest('.btn-admin-trad, .btn-bib-trad');
|
||
if (btnTrad) {
|
||
e.preventDefault();
|
||
e.stopPropagation();
|
||
let url = btnTrad.getAttribute('data-trad-url');
|
||
if (!url) {
|
||
return;
|
||
}
|
||
let clef = btnTrad.getAttribute('data-info-clef') || 'bib_trad';
|
||
let popup = window.open(
|
||
url,
|
||
'bib_trad_' + clef,
|
||
'width=960,height=640,scrollbars=yes,resizable=yes'
|
||
);
|
||
if (popup) {
|
||
let timer = setInterval(function () {
|
||
if (popup.closed) {
|
||
clearInterval(timer);
|
||
window.location.reload();
|
||
}
|
||
}, 400);
|
||
}
|
||
return;
|
||
}
|
||
|
||
// =====================
|
||
// LOCK / UNLOCK SEQUENCE
|
||
// =====================
|
||
let btnLock = e.target.closest('.btn-bib-lock');
|
||
if (btnLock) {
|
||
e.preventDefault();
|
||
|
||
let row = btnLock.closest('.epr-row');
|
||
if (!row) return;
|
||
|
||
// MSIN-4469 — Impression : pas de bascule du cadenas humain.
|
||
if (btnLock.disabled || bibRowIsProductionLocked(row)) {
|
||
bibAlertProductionLocked();
|
||
return;
|
||
}
|
||
|
||
let isLocked = btnLock.dataset.locked === '1';
|
||
let confirmMsg = isLocked
|
||
? bibJsConfirm('jsUnlockConfirm')
|
||
: bibJsConfirm('jsLockConfirm');
|
||
|
||
if (!confirm(confirmMsg)) {
|
||
return;
|
||
}
|
||
|
||
bibFetch('/ajax_bib_range.php', {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/x-www-form-urlencoded'
|
||
},
|
||
body:
|
||
'action=toggle_lock'
|
||
+ '&epr_bib_id=' + encodeURIComponent(btnLock.dataset.rangeId)
|
||
+ '&epr_id=' + encodeURIComponent(btnLock.dataset.eprId || row.dataset.eprId)
|
||
+ '&locked=' + encodeURIComponent(isLocked ? '0' : '1')
|
||
+ bibAjaxLangSuffix()
|
||
})
|
||
.then(res => res.json())
|
||
.then(data => {
|
||
|
||
if (!data.success) {
|
||
alert(data.message || bibJs('jsErrGeneric'));
|
||
return;
|
||
}
|
||
|
||
if (typeof data.auto_active !== 'undefined') {
|
||
row.dataset.autoActive = data.auto_active ? '1' : '0';
|
||
syncAutoUiState(row, data.auto_active);
|
||
syncBibUiState(row);
|
||
}
|
||
|
||
if (data.html) {
|
||
setBibContainerFromAjax(row, data);
|
||
bibSyncResetAllEprButton(row);
|
||
}
|
||
});
|
||
|
||
return;
|
||
}
|
||
|
||
// =====================
|
||
// MSIN-4436 — Réinitialiser tous les dossards (épreuve entière)
|
||
// =====================
|
||
let btnResetAllEpr = e.target.closest('.btn-reset-all-epr');
|
||
if (btnResetAllEpr) {
|
||
|
||
e.preventDefault();
|
||
|
||
let row = btnResetAllEpr.closest('.epr-row');
|
||
if (!row) {
|
||
return;
|
||
}
|
||
|
||
if (bibRowIsProductionLocked(row)) {
|
||
bibAlertProductionLocked();
|
||
return;
|
||
}
|
||
|
||
if (btnResetAllEpr.disabled) {
|
||
alert(bibJsConfirm('jsResetAllLocked'));
|
||
return;
|
||
}
|
||
|
||
if (row.querySelector('.btn-bib-commande-lock--assign')) {
|
||
alert(bibJsConfirm('jsResetAllLocked'));
|
||
bibSyncResetAllEprButton(row);
|
||
return;
|
||
}
|
||
|
||
if (!confirm(bibJsConfirm('jsResetAllConfirm'))) {
|
||
return;
|
||
}
|
||
|
||
bibFetch('/ajax_bib_range.php', {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/x-www-form-urlencoded'
|
||
},
|
||
body:
|
||
'action=reset_all_apply'
|
||
+ '&epr_id=' + encodeURIComponent(row.dataset.eprId)
|
||
+ bibAjaxLangSuffix()
|
||
}, { loader: true })
|
||
.then(res => res.json())
|
||
.then(data => {
|
||
|
||
if (!data.success) {
|
||
alert(data.message || bibJs('jsErrGeneric'));
|
||
return;
|
||
}
|
||
|
||
// MSIN-4528 — même chemin que reset séquence (pas de grille HTML).
|
||
return bibAfterBatchGoSuccess(row, data, true);
|
||
});
|
||
|
||
return;
|
||
}
|
||
|
||
// =====================
|
||
// DELETE
|
||
// =====================
|
||
let btnDelete = e.target.closest('.btn-delete-range');
|
||
if (btnDelete) {
|
||
|
||
|
||
e.preventDefault();
|
||
|
||
let container = btnDelete.closest('.bib-container');
|
||
let errorDiv = container.querySelector('.bib-error-global');
|
||
|
||
// reset erreur
|
||
if (errorDiv) {
|
||
errorDiv.style.display = 'none';
|
||
errorDiv.innerText = '';
|
||
}
|
||
|
||
let id = btnDelete.dataset.id;
|
||
if (!id) return;
|
||
|
||
let rowDelete = btnDelete.closest('.epr-row');
|
||
let eprIdDelete = rowDelete ? rowDelete.dataset.eprId : '';
|
||
|
||
bibFetch('/ajax_bib_range.php', {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/x-www-form-urlencoded'
|
||
},
|
||
body: 'action=delete'
|
||
+ '&id=' + encodeURIComponent(id)
|
||
+ '&epr_id=' + encodeURIComponent(eprIdDelete)
|
||
+ bibAjaxLangSuffix()
|
||
})
|
||
.then(res => res.text())
|
||
.then(raw => {
|
||
|
||
let data;
|
||
try {
|
||
data = JSON.parse(raw);
|
||
} catch (err) {
|
||
if (errorDiv) {
|
||
errorDiv.innerText = bibJs('jsServerError');
|
||
errorDiv.style.display = 'block';
|
||
}
|
||
return;
|
||
}
|
||
|
||
if (!data.success) {
|
||
if (errorDiv) {
|
||
errorDiv.innerText = data.message || bibJs('jsErrGeneric');
|
||
errorDiv.style.display = 'block';
|
||
}
|
||
return;
|
||
}
|
||
|
||
// MSIN-4446 — Rafraîchir aussi la pastille « N séquence(s) ».
|
||
setBibContainerFromAjax(btnDelete.closest('.epr-row'), data);
|
||
});
|
||
|
||
return;
|
||
}
|
||
|
||
// =====================
|
||
// SAVE
|
||
// =====================
|
||
let btnSave = e.target.closest('.btn-save-range');
|
||
if (btnSave) {
|
||
e.preventDefault();
|
||
|
||
let row = btnSave.closest('.bib-range');
|
||
let errorDiv = row.nextElementSibling;
|
||
let epr_id = btnSave.dataset.eprId;
|
||
|
||
// reset
|
||
if (errorDiv) {
|
||
errorDiv.style.display = 'none';
|
||
errorDiv.innerText = '';
|
||
}
|
||
|
||
applyBibRangeFieldState(row);
|
||
|
||
let start = bibRangeParseInt(row.querySelector('.bib-start').value);
|
||
let end = bibRangeParseInt(row.querySelector('.bib-end').value);
|
||
let id = btnSave.dataset.id;
|
||
let validation = bibRangeValidate(row);
|
||
|
||
// ligne temporaire vide = on la retire
|
||
if (id == 0 && start <= 0) {
|
||
row.remove();
|
||
if (errorDiv && errorDiv.classList.contains('bib-error')) {
|
||
errorDiv.remove();
|
||
}
|
||
return;
|
||
}
|
||
|
||
if (start <= 0 || end <= 0) {
|
||
validation = validation || { key: 'incomplete' };
|
||
}
|
||
|
||
if (!validation && end < start) {
|
||
validation = { key: 'invalidEnd', field: 'end', start: start };
|
||
}
|
||
|
||
if (validation) {
|
||
bibRangeShowValidation(row, validation);
|
||
if (errorDiv) {
|
||
var msgEl = errorDiv.querySelector('.bib-range-validate-msg');
|
||
if (!msgEl) {
|
||
errorDiv.innerText = bibRangeValidationMessage(validation);
|
||
}
|
||
errorDiv.style.display = 'block';
|
||
}
|
||
var invalidField = validation.field === 'qty'
|
||
? row.querySelector('.bib-qty')
|
||
: row.querySelector('.bib-end');
|
||
if (invalidField) {
|
||
invalidField.focus();
|
||
}
|
||
return;
|
||
}
|
||
|
||
bibFetch('/ajax_bib_range.php', {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/x-www-form-urlencoded'
|
||
},
|
||
body:
|
||
'action=save'
|
||
+ '&id=' + encodeURIComponent(id)
|
||
+ '&epr_id=' + encodeURIComponent(epr_id)
|
||
+ '&start=' + encodeURIComponent(start)
|
||
+ '&end=' + encodeURIComponent(end)
|
||
+ bibAjaxLangSuffix()
|
||
})
|
||
.then(res => res.text())
|
||
.then(raw => {
|
||
|
||
let data;
|
||
try {
|
||
data = JSON.parse(raw);
|
||
} catch (err) {
|
||
errorDiv.innerText = bibJs('jsServerError');
|
||
errorDiv.style.display = 'block';
|
||
return;
|
||
}
|
||
|
||
if (!data.success) {
|
||
errorDiv.innerText = data.message || bibJs('jsErrGeneric');
|
||
errorDiv.style.display = 'block';
|
||
return;
|
||
}
|
||
|
||
setBibContainerFromAjax(btnSave.closest('.epr-row'), data);
|
||
});
|
||
|
||
return;
|
||
}
|
||
// =====================
|
||
// VIEW
|
||
// =====================
|
||
let btnView = e.target.closest('.btn-view-range');
|
||
if (btnView) {
|
||
e.preventDefault();
|
||
|
||
let epr_id = btnView.dataset.eprId;
|
||
let range_id = btnView.dataset.rangeId;
|
||
|
||
console.log('epr_id:', epr_id);
|
||
console.log('range_id:', range_id);
|
||
if (!epr_id || typeof range_id === 'undefined') return;
|
||
|
||
let container = btnView.closest('.epr-block');
|
||
|
||
// Vérifier si une vue est déjà ouverte
|
||
let existing = document.querySelector('.epr-row-view');
|
||
|
||
// Toggle : si c'est le même œil qui a ouvert la vue, on la ferme et on s'arrête
|
||
if (existing
|
||
&& existing.dataset.eprId === epr_id
|
||
&& existing.dataset.rangeId === range_id
|
||
) {
|
||
existing.remove();
|
||
return;
|
||
}
|
||
|
||
// Un autre œil a été cliqué : fermer la vue précédente avant d'ouvrir la nouvelle
|
||
if (existing) {
|
||
existing.remove();
|
||
}
|
||
|
||
bibFetch('/ajax_bib_range.php', {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/x-www-form-urlencoded'
|
||
},
|
||
body:
|
||
'action=view'
|
||
+ '&epr_id=' + encodeURIComponent(epr_id)
|
||
+ '&range_id=' + encodeURIComponent(range_id)
|
||
+ bibAjaxLangSuffix()
|
||
}, { loader: true })
|
||
.then(res => res.text())
|
||
.then(raw => {
|
||
|
||
let data;
|
||
try {
|
||
data = JSON.parse(raw);
|
||
} catch (err) {
|
||
console.log(bibJs('jsServerError'));
|
||
return;
|
||
}
|
||
|
||
if (!data.success) {
|
||
console.log(data.message || bibJs('jsErrGeneric'));
|
||
return;
|
||
}
|
||
|
||
let row = btnView.closest('.epr-row');
|
||
|
||
// Injecter la nouvelle vue sous la ligne du bouton cliqué,
|
||
// en mémorisant epr_id et range_id pour le toggle suivant
|
||
row.insertAdjacentHTML('afterend', data.html);
|
||
|
||
// Stocker les identifiants sur la vue injectée pour pouvoir détecter
|
||
// le 2e clic sur le même œil
|
||
let newView = row.nextElementSibling;
|
||
if (newView && newView.classList.contains('epr-row-view')) {
|
||
newView.dataset.eprId = epr_id;
|
||
newView.dataset.rangeId = range_id;
|
||
}
|
||
});
|
||
|
||
return;
|
||
}
|
||
|
||
|
||
// =====================
|
||
// CLOSE VIEW
|
||
// =====================
|
||
let btnClose = e.target.closest('.btn-close-view');
|
||
if (btnClose) {
|
||
e.preventDefault();
|
||
|
||
let view = btnClose.closest('.epr-row-view');
|
||
if (view) {
|
||
view.remove();
|
||
}
|
||
|
||
return;
|
||
}
|
||
// =====================
|
||
// ASSIGN BATCH
|
||
// =====================
|
||
// Active/désactive le mode batch pour UNE épreuve.
|
||
// - Affiche les checkbox
|
||
// - Bloque Début/Fin
|
||
// - Affiche le bloc de configuration
|
||
// - Recalcule l’analyse initiale
|
||
// =====================
|
||
let btnBatch = e.target.closest('.btn-assign-batch');
|
||
if (btnBatch) {
|
||
|
||
e.preventDefault();
|
||
|
||
let row = btnBatch.closest('.epr-row');
|
||
if (!row) return;
|
||
|
||
if (btnBatch.disabled) {
|
||
return;
|
||
}
|
||
|
||
// MSIN-4379 — Batch et auto sont mutuellement exclusifs.
|
||
if (row.classList.contains('auto-mode')) {
|
||
return;
|
||
}
|
||
|
||
let container = row.querySelector('.bib-container');
|
||
if (!container) return;
|
||
|
||
// OFF — MSIN-4564 : sortie via Fermer en bas (garde-fou si reclic).
|
||
if (row.classList.contains('batch-mode')) {
|
||
exitBatchOrResetMode(row);
|
||
return;
|
||
}
|
||
|
||
// ON — MSIN-4530 : décoche à l’entrée (séquence d’abord).
|
||
// MSIN-4564 — ne plus transformer le bouton en « Annuler ».
|
||
row.classList.add('batch-mode');
|
||
container.classList.add('batch-mode');
|
||
|
||
row.querySelectorAll('.bib-start, .bib-qty, .bib-end').forEach(input => {
|
||
input.setAttribute('readonly', true);
|
||
});
|
||
|
||
row.querySelectorAll('.batch-select-range').forEach(function (cb) {
|
||
cb.checked = false;
|
||
});
|
||
|
||
let goBtn = row.querySelector('.btn-go-batch');
|
||
if (goBtn) {
|
||
goBtn.textContent = row.dataset.goLabel || goBtn.textContent;
|
||
}
|
||
if (typeof updateBatchAnalysis === 'function') {
|
||
updateBatchAnalysis(row);
|
||
}
|
||
syncBibUiState(row);
|
||
|
||
return;
|
||
}
|
||
// =====================
|
||
// SIMULER BATCH
|
||
// =====================
|
||
let btnSim = e.target.closest('.btn-simuler-batch');
|
||
if (btnSim) {
|
||
|
||
e.preventDefault();
|
||
|
||
let row = btnSim.closest('.epr-row');
|
||
if (!row) return;
|
||
|
||
let selected = [];
|
||
|
||
row.querySelectorAll('.batch-select-range:checked').forEach(cb => {
|
||
selected.push(cb.dataset.rangeId);
|
||
});
|
||
|
||
if (selected.length === 0) {
|
||
alert(bibJs('jsNoSeqSelected'));
|
||
return;
|
||
}
|
||
let isResetMode = row.dataset.mode === 'reset';
|
||
let sortKeys = bibGetRowSortKeys(row);
|
||
|
||
bibFetch('/ajax_bib_range.php', {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/x-www-form-urlencoded'
|
||
},
|
||
body:
|
||
(isResetMode ? 'action=reset_preview' : 'action=batch_go')
|
||
+ '&epr_id=' + encodeURIComponent(row.dataset.eprId)
|
||
+ '&ranges=' + encodeURIComponent(JSON.stringify(selected))
|
||
+ bibAppendBatchSortParams('', sortKeys)
|
||
+ (isResetMode ? '' : bibAppendTeamModeParam('', row))
|
||
+ bibAjaxLangSuffix()
|
||
}, { loader: true })
|
||
.then(res => res.json())
|
||
.then(data => {
|
||
|
||
if (!data.success) {
|
||
alert(data.message || bibJs('jsErrGeneric'));
|
||
return;
|
||
}
|
||
|
||
let existing = document.querySelector('.epr-row-view');
|
||
if (existing) {
|
||
existing.remove();
|
||
}
|
||
|
||
row.insertAdjacentHTML('afterend', data.html);
|
||
|
||
|
||
});
|
||
|
||
return;
|
||
}
|
||
|
||
// =====================
|
||
// RESET MODE
|
||
// =====================
|
||
let btnReset = e.target.closest('.btn-reset');
|
||
if (btnReset) {
|
||
|
||
e.preventDefault();
|
||
|
||
let row = btnReset.closest('.epr-row');
|
||
if (!row) return;
|
||
|
||
// MSIN-4469 — Impression : pas de réassign / reset.
|
||
if (btnReset.disabled || bibRowIsProductionLocked(row)) {
|
||
bibAlertProductionLocked();
|
||
return;
|
||
}
|
||
|
||
// MSIN-4379 — Reset et auto sont mutuellement exclusifs.
|
||
if (row.classList.contains('auto-mode')) {
|
||
return;
|
||
}
|
||
|
||
let container = row.querySelector('.bib-container');
|
||
if (!container) return;
|
||
|
||
// =====================
|
||
// OFF — MSIN-4564 : sortie via Fermer en bas (garde-fou si reclic).
|
||
// =====================
|
||
if (row.classList.contains('reset-mode')) {
|
||
exitBatchOrResetMode(row);
|
||
return;
|
||
}
|
||
|
||
// =====================
|
||
// ON — MSIN-4526 : mode local, pas de refresh_ranges (CTE trous).
|
||
// MSIN-4564 — ne plus transformer le bouton en « Annuler ».
|
||
// =====================
|
||
row.classList.add('reset-mode');
|
||
row.dataset.mode = 'reset';
|
||
container.classList.add('batch-mode');
|
||
|
||
row.querySelectorAll('.bib-start, .bib-qty, .bib-end').forEach(input => {
|
||
input.setAttribute('readonly', true);
|
||
});
|
||
|
||
row.querySelectorAll('.batch-select-range').forEach(function (cb) {
|
||
cb.checked = false;
|
||
});
|
||
|
||
let goBtn = row.querySelector('.btn-go-batch');
|
||
if (goBtn) {
|
||
goBtn.textContent = row.dataset.resetLabel || goBtn.textContent;
|
||
}
|
||
|
||
syncBibUiState(row);
|
||
|
||
return;
|
||
}
|
||
|
||
|
||
|
||
|
||
// =====================
|
||
// MSIN-4564 — FERMER (batch / reset)
|
||
// =====================
|
||
let btnFermerAssign = e.target.closest('.btn-fermer-assign');
|
||
if (btnFermerAssign) {
|
||
e.preventDefault();
|
||
let row = btnFermerAssign.closest('.epr-row');
|
||
if (!row) return;
|
||
exitBatchOrResetMode(row);
|
||
return;
|
||
}
|
||
|
||
// =====================
|
||
// GO BATCH
|
||
// =====================
|
||
let btnGo = e.target.closest('.btn-go-batch');
|
||
if (btnGo) {
|
||
|
||
e.preventDefault();
|
||
|
||
let row = btnGo.closest('.epr-row');
|
||
if (!row) return;
|
||
|
||
let selected = [];
|
||
|
||
row.querySelectorAll('.batch-select-range:checked').forEach(cb => {
|
||
selected.push(cb.dataset.rangeId);
|
||
});
|
||
|
||
if (selected.length === 0) {
|
||
alert(bibJs('jsNoSeqSelected'));
|
||
return;
|
||
}
|
||
let isResetMode = row.dataset.mode === 'reset';
|
||
let sortKeys = bibGetRowSortKeys(row);
|
||
|
||
if (isResetMode) {
|
||
bibFetch('/ajax_bib_range.php', {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/x-www-form-urlencoded'
|
||
},
|
||
body:
|
||
'action=reset_apply'
|
||
+ '&epr_id=' + encodeURIComponent(row.dataset.eprId)
|
||
+ '&ranges=' + encodeURIComponent(JSON.stringify(selected))
|
||
+ bibAppendBatchSortParams('', sortKeys)
|
||
+ bibAjaxLangSuffix()
|
||
}, { loader: true })
|
||
.then(res => res.json())
|
||
.then(data => {
|
||
|
||
if (!data.success) {
|
||
alert(data.message || bibJs('jsErrGeneric'));
|
||
return;
|
||
}
|
||
|
||
return bibAfterBatchGoSuccess(row, data, true);
|
||
});
|
||
|
||
return;
|
||
}
|
||
|
||
bibRunBatchApplyChunks(row, selected, sortKeys);
|
||
|
||
return;
|
||
}
|
||
|
||
// =====================
|
||
// MSIN-4379 — Étape 2 : AUTO DOSSARD (clics Accepter / Annuler / Désactiver / Activer)
|
||
// Prochain tour : étape 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 (btnAuto.disabled) {
|
||
return;
|
||
}
|
||
|
||
if (row.classList.contains('batch-mode') || row.classList.contains('reset-mode')) {
|
||
return;
|
||
}
|
||
|
||
enterAutoMode(row);
|
||
return;
|
||
}
|
||
|
||
// =====================
|
||
// CREATE
|
||
// =====================
|
||
|
||
let btn = e.target.closest('.btn-add-range');
|
||
if (!btn) return;
|
||
|
||
e.preventDefault();
|
||
|
||
let container = btn.closest('.bib-container');
|
||
let errorDiv = container.querySelector('.bib-error-global');
|
||
|
||
// reset
|
||
if (errorDiv) {
|
||
errorDiv.style.display = 'none';
|
||
errorDiv.innerText = '';
|
||
}
|
||
|
||
let epr_id = btn.dataset.eprId;
|
||
if (!epr_id) return;
|
||
|
||
bibFetch('/ajax_bib_range.php', {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/x-www-form-urlencoded'
|
||
},
|
||
body: 'action=create&epr_id=' + encodeURIComponent(epr_id) + bibAjaxLangSuffix()
|
||
})
|
||
.then(res => res.text())
|
||
.then(raw => {
|
||
|
||
let data;
|
||
try {
|
||
data = JSON.parse(raw);
|
||
} catch (err) {
|
||
if (errorDiv) {
|
||
errorDiv.innerText = bibJs('jsServerError');
|
||
errorDiv.style.display = 'block';
|
||
}
|
||
return;
|
||
}
|
||
|
||
if (!data.success) {
|
||
console.log('CREATE ERROR:', data);
|
||
console.log('container:', container);
|
||
console.log('errorDiv:', errorDiv);
|
||
if (errorDiv) {
|
||
errorDiv.innerText = data.message || bibJs('jsErrGeneric');
|
||
errorDiv.style.display = 'block';
|
||
}
|
||
return;
|
||
}
|
||
|
||
setBibContainerFromAjax(btn.closest('.epr-row'), data);
|
||
});
|
||
});
|
||
|
||
function syncBibEventConfigHeaderNote() {
|
||
let chk = moduleBib.querySelector('.bib-event-allow-inter-epr');
|
||
if (!chk) {
|
||
return;
|
||
}
|
||
document.querySelectorAll('[data-bib-inter-epr-note]').forEach(function (note) {
|
||
note.classList.toggle('bib-ui-hidden', !chk.checked);
|
||
});
|
||
}
|
||
|
||
// MSIN-4424 — Autoriser mêmes numéros entre épreuves (réglage événement).
|
||
let chkAllowInterEpr = moduleBib.querySelector('.bib-event-allow-inter-epr');
|
||
if (chkAllowInterEpr) {
|
||
chkAllowInterEpr.addEventListener('change', function () {
|
||
let eveId = moduleBib.dataset.eveId || '';
|
||
if (!eveId) {
|
||
return;
|
||
}
|
||
|
||
bibFetch('/ajax_bib_range.php', {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/x-www-form-urlencoded'
|
||
},
|
||
body:
|
||
'action=save_allow_inter_epr'
|
||
+ '&eve_id=' + encodeURIComponent(eveId)
|
||
+ '&allow=' + (chkAllowInterEpr.checked ? '1' : '0')
|
||
+ bibAjaxLangSuffix()
|
||
})
|
||
.then(function (res) { return res.json(); })
|
||
.then(function (data) {
|
||
if (!data.success) {
|
||
chkAllowInterEpr.checked = !chkAllowInterEpr.checked;
|
||
alert(data.message || bibJs('jsErrGeneric'));
|
||
return;
|
||
}
|
||
|
||
moduleBib.dataset.allowInterEpr = data.allow_inter_epr ? '1' : '0';
|
||
syncBibEventConfigHeaderNote();
|
||
|
||
let mount = document.getElementById('bib-anomalies-mount');
|
||
if (mount && data.anomalies_html) {
|
||
let blnWasActive = bibActiveTool === 'anomalies';
|
||
if (blnWasActive) {
|
||
bibRestoreToolContent('anomalies');
|
||
}
|
||
bibInvalidateToolSlot('anomalies');
|
||
mount.innerHTML = data.anomalies_html;
|
||
initModuleBibTippy(mount);
|
||
bibSyncToolNavBadges('anomalies');
|
||
bibRemountActiveToolAfterRefresh('anomalies');
|
||
}
|
||
|
||
if (bibQtySummaryShouldRefresh()) {
|
||
refreshBibQtySummaryPanel();
|
||
}
|
||
})
|
||
.catch(function () {
|
||
chkAllowInterEpr.checked = !chkAllowInterEpr.checked;
|
||
alert(bibJs('jsErrGeneric'));
|
||
});
|
||
});
|
||
}
|
||
|
||
// MSIN-4436 — Anomalies : coquille légère au chargement, détail en AJAX.
|
||
if (document.querySelector('#bib-anomalies-panel[data-bib-anomalies-deferred="1"]')) {
|
||
refreshBibAnomaliesPanel().then(function () {
|
||
bibSyncAllToolNavBadges();
|
||
bibApplyFocusFromUrlOnce();
|
||
});
|
||
} else {
|
||
bibSyncAllToolNavBadges();
|
||
bibApplyFocusFromUrlOnce();
|
||
}
|
||
}
|
||
})();
|