Astreinte : supprimer une intervention l'enregistre immédiatement
Le bouton × retirait la ligne de l'écran sans déclencher la sauvegarde :
au rechargement, l'intervention supprimée réapparaissait. La suppression
enregistre maintenant le jour dès le clic (asDelEvent → asSaveDay).
💘 Generated with Crush
Assisted-by: Crush:glm-5.2
This commit is contained in:
@ -375,10 +375,14 @@ document.addEventListener('input', function(e) {
|
||||
var timer = null;
|
||||
var pendingDate = null;
|
||||
|
||||
function triggerSave(date) {
|
||||
// Déclenche la sauvegarde du jour depuis le témoin .autosave (attributs hx-*),
|
||||
// exposé globalement : utilisé par le debounce ci-dessous et par la
|
||||
// suppression d'une ligne d'intervention, qui doit être enregistrée
|
||||
// immédiatement — sinon elle réapparaît au rechargement.
|
||||
window.asSaveDay = function (date) {
|
||||
var trig = document.getElementById('save-' + date);
|
||||
if (trig) htmx.trigger(trig, 'save-day');
|
||||
}
|
||||
};
|
||||
|
||||
// Le swap OOB remplace les champs du jour : si le focus était dedans
|
||||
// (ex. tabulation entrée → sortie), on le restaure sur le champ équivalent.
|
||||
@ -395,7 +399,7 @@ document.addEventListener('input', function(e) {
|
||||
}
|
||||
pendingDate = date;
|
||||
clearTimeout(timer);
|
||||
timer = setTimeout(function () { triggerSave(pendingDate); }, 350);
|
||||
timer = setTimeout(function () { asSaveDay(pendingDate); }, 350);
|
||||
});
|
||||
|
||||
document.body.addEventListener('htmx:afterSwap', function () {
|
||||
@ -502,6 +506,18 @@ document.addEventListener('htmx:afterSwap', asRestore);
|
||||
// settle, dernier moment du cycle.
|
||||
document.addEventListener('htmx:afterSettle', asRestore);
|
||||
|
||||
// Supprime une ligne d'intervention et enregistre le jour immédiatement :
|
||||
// sans sauvegarde, la ligne ne disparaîtrait que visuellement et reviendrait
|
||||
// au rechargement (l'autosave ne se déclenche que sur change d'un champ).
|
||||
window.asDelEvent = function (btn) {
|
||||
var ev = btn.closest('.as-event');
|
||||
if (!ev) return;
|
||||
var input = ev.querySelector('[data-date]');
|
||||
var date = input ? input.dataset.date : null;
|
||||
ev.remove();
|
||||
if (date) asSaveDay(date);
|
||||
};
|
||||
|
||||
// Ajoute une ligne d'intervention vierge dans le jour ciblé
|
||||
window.asAddEvent = function (date) {
|
||||
var grid = document.getElementById('as-events-' + date);
|
||||
@ -513,7 +529,7 @@ window.asAddEvent = function (date) {
|
||||
'<input class="time-input" type="time" name="astreinte_fin" data-date="' + date + '" value="">' +
|
||||
'<div class="as-desc-cell">' +
|
||||
'<input type="text" class="as-desc" name="astreinte_desc" data-date="' + date + '" maxlength="200" placeholder="description" value="">' +
|
||||
'<button type="button" class="as-del" title="Supprimer" onclick="this.closest(\'.as-event\').remove()">×</button>' +
|
||||
'<button type="button" class="as-del" title="Supprimer" onclick="asDelEvent(this)">×</button>' +
|
||||
'</div>';
|
||||
grid.appendChild(ev);
|
||||
};
|
||||
|
||||
@ -81,3 +81,48 @@ def test_ligne_entierement_vide_non_conservee():
|
||||
"astreinte_desc": ["", ""]}, follow_redirects=False)
|
||||
# La ligne vide n'est pas stockée, la ligne complète l'est
|
||||
assert _events(uid, "2026-07-14") == [{"debut": "22:00", "fin": "23:00", "desc": None}]
|
||||
|
||||
|
||||
def test_suppression_dune_ligne_persiste():
|
||||
"""Le bouton × retire la ligne du DOM puis enregistre le jour : le POST ne
|
||||
contient plus que les lignes restantes, la supprimée doit disparaître."""
|
||||
uid = "u-as-del"
|
||||
cookies = _login(uid)
|
||||
models.toggle_astreinte("2026-07-14", uid)
|
||||
|
||||
client.post("/pointage/2026-07-14", cookies=cookies,
|
||||
data={"astreinte_debut": ["22:00", "23:00"], "astreinte_fin": ["22:30", "23:30"],
|
||||
"astreinte_desc": ["", ""]}, follow_redirects=False)
|
||||
assert len(_events(uid, "2026-07-14") or []) == 2
|
||||
|
||||
# La 1re ligne est supprimée : seule la 2e reste dans le POST
|
||||
r = client.post("/pointage/2026-07-14", cookies=cookies,
|
||||
data={"astreinte_debut": ["23:00"], "astreinte_fin": ["23:30"],
|
||||
"astreinte_desc": [""]}, follow_redirects=False)
|
||||
assert r.status_code == 200, r.text
|
||||
assert _events(uid, "2026-07-14") == [{"debut": "23:00", "fin": "23:30", "desc": None}]
|
||||
|
||||
# Suppression de la dernière ligne : plus aucun champ astreinte dans le POST
|
||||
r = client.post("/pointage/2026-07-14", cookies=cookies,
|
||||
data={"astreinte_debut": [], "astreinte_fin": [],
|
||||
"astreinte_desc": []}, follow_redirects=False)
|
||||
assert r.status_code == 200, r.text
|
||||
assert _events(uid, "2026-07-14") == []
|
||||
|
||||
|
||||
def test_bouton_suppression_câble_lenregistrement():
|
||||
"""Le × doit déclencher la sauvegarde du jour (asDelEvent), sans quoi la
|
||||
ligne ne disparaît que visuellement et revient au rechargement."""
|
||||
uid = "u-as-del-html"
|
||||
cookies = _login(uid)
|
||||
models.toggle_astreinte("2026-07-14", uid)
|
||||
client.post("/pointage/2026-07-14", cookies=cookies,
|
||||
data={"astreinte_debut": ["22:00"], "astreinte_fin": ["22:30"],
|
||||
"astreinte_desc": [""]}, follow_redirects=False)
|
||||
|
||||
r = client.get("/semaine/2026/29", cookies=cookies, follow_redirects=False)
|
||||
assert r.status_code == 200, r.text
|
||||
# Le bouton rendu appelle asDelEvent, défini (avec asSaveDay) dans la page
|
||||
assert 'onclick="asDelEvent(this)"' in r.text
|
||||
assert "window.asDelEvent" in r.text
|
||||
assert "window.asSaveDay" in r.text
|
||||
|
||||
Reference in New Issue
Block a user