Build and deploy / test-python (push) Successful in 11m18s
Build and deploy / test-js (push) Successful in 1m16s
Build and deploy / lint-python (push) Successful in 4m24s
Build and deploy / lint-js (push) Successful in 2m51s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
Build and deploy / sonarqube (push) Successful in 5m30s
Corrige les findings SonarQube (via SonarLint IDE, fichier par fichier) sur ~24 fichiers static/js/ : parseFloat/parseInt -> Number.*, .replace(/x/g,y) -> .replaceAll, .indexOf() -> .includes()/.startsWith(), getAttribute/setAttribute -> .dataset, tableaux -> Set, x && x.y -> x?.y (verifie site par site), extraction de template litteraux imbriques, ternaires imbriquees, refactors de complexite cognitive (S3776) via tables de dispatch, Object.hasOwn, .at(), et deduplication de fonctions identiques (S4144). Deux exceptions S2486 documentees/corrigees (filter-repeater-rows.js) et un cas S2703 de partage inter-scripts complete (_collisionWizard, trigger-editor.js <-> collision-rules-editor.js). Details complets dans CODE_QUALITY.md section 5. Restaure aussi le job CI "sonarqube" (non-bloquant) dans .gitea/workflows/deploy.yml maintenant que l'instance prod est operationnelle. Suites vertes : 276/276 JS (node --test), 591/591 Python (pytest). SKIP=djlint sur ce commit : hook djlint bloquant sur le backlog H021 (styles inline, 49 occurrences/6 templates) deja documente comme dette assumee non traitee dans CODE_QUALITY.md section 6, aucun rapport avec ce commit (aucun template touche ici) - valide explicitement avec l'utilisateur avant de contourner ce hook. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
68 lines
2.9 KiB
JavaScript
68 lines
2.9 KiB
JavaScript
// ---------- Onglet "Variables" — CRUD en AJAX ----------
|
|
// Demande explicite : modifier/supprimer une variable rechargeait toute
|
|
// la page (formulaires classiques + navigation pjax) — remplacé par de
|
|
// vrais appels fetch(), sans jamais recharger ni naviguer.
|
|
|
|
// Enregistre automatiquement dès qu'un champ (type/valeur) change — plus
|
|
// besoin d'un bouton "Enregistrer" séparé (demande explicite : "que la
|
|
// modification s'enregistre automatiquement").
|
|
function saveGlobalVariable(varId) {
|
|
const row = document.querySelector(`tr[data-var-row="${varId}"]`);
|
|
if (!row) return;
|
|
const type = row.querySelector('select[name="type"]').value;
|
|
const { value } = row.querySelector('input[name="value"]');
|
|
const status = document.getElementById(`varSaveStatus${varId}`);
|
|
const body = new FormData();
|
|
body.append('type', type);
|
|
body.append('value', value);
|
|
fetch(`/game/${GAME_SLUG}/variables/${varId}/edit`, {
|
|
method: 'POST', headers: { 'X-Requested-With': 'fetch' }, body,
|
|
})
|
|
.then((r) => {
|
|
if (!r.ok) { window.location.reload(); return; }
|
|
if (status) {
|
|
status.textContent = 'Enregistré ✓';
|
|
setTimeout(() => { status.textContent = ''; }, 2000);
|
|
}
|
|
})
|
|
.catch(() => { window.location.reload(); });
|
|
}
|
|
|
|
function deleteGlobalVariable(varId, name) {
|
|
if (!window.confirm(`Supprimer la variable « ${name} » ? Toute condition/action qui la référence encore cessera de fonctionner.`)) return;
|
|
const body = new FormData();
|
|
fetch(`/game/${GAME_SLUG}/variables/${varId}/delete`, {
|
|
method: 'POST', headers: { 'X-Requested-With': 'fetch' }, body,
|
|
})
|
|
.then((r) => {
|
|
if (!r.ok) { window.location.reload(); return; }
|
|
const row = document.querySelector(`tr[data-var-row="${varId}"]`);
|
|
if (row) row.remove();
|
|
const body2 = document.getElementById('globalVariablesBody');
|
|
const emptyHint = document.getElementById('globalVariablesEmptyHint');
|
|
if (body2 && emptyHint) emptyHint.style.display = body2.children.length ? 'none' : '';
|
|
})
|
|
.catch(() => { window.location.reload(); });
|
|
}
|
|
|
|
function createGlobalVariable(event) {
|
|
event.preventDefault();
|
|
const form = event.target;
|
|
const body = new FormData(form);
|
|
fetch(`/game/${GAME_SLUG}/variables/new`, {
|
|
method: 'POST', headers: { 'X-Requested-With': 'fetch' }, body,
|
|
})
|
|
.then((r) => (r.ok ? r.json() : Promise.reject(new Error(`HTTP ${r.status}`))))
|
|
.then((json) => {
|
|
if (!json.row_html) { window.location.reload(); return; }
|
|
const tbody = document.getElementById('globalVariablesBody');
|
|
tbody.insertAdjacentHTML('beforeend', json.row_html);
|
|
const emptyHint = document.getElementById('globalVariablesEmptyHint');
|
|
if (emptyHint) emptyHint.style.display = 'none';
|
|
form.reset();
|
|
form.style.display = 'none'; // même comportement que toggleDashCreate() après création
|
|
})
|
|
.catch(() => { window.location.reload(); });
|
|
return false;
|
|
}
|