IT-Stock/app/templates/materiels.html
maxsoch 7ce6540924 Refonte des listings et arborescence de catégories à profondeur illimitée
Catégorie/SousCategorie fusionnées en un seul modèle auto-référencé
(parent_id), pour permettre une imbrication sans limite de niveaux. Les
listings matériels/catégories/destinataires passent en lignes repliées
(<details>) avec recherche côté serveur, ce qui corrige le débordement
horizontal du tableau tout-en-input et reste utilisable sur de longues
listes. Style de l'écran de scan également retravaillé (frontend-design).
2026-07-14 19:06:37 +02:00

87 lines
3.7 KiB
HTML

{% extends "base.html" %}
{% block titre %}Matériels - Gestion de stock IT{% endblock %}
{% block contenu %}
<h1>Matériels</h1>
<form method="get" action="/materiels" class="barre-recherche">
<input type="search" name="q" value="{{ q }}" placeholder="Rechercher par nom ou code-barre…">
{% if q %}<a href="/materiels" class="lien-effacer">Effacer</a>{% endif %}
</form>
{#
Chaque ligne est repliée par défaut (juste le résumé, pas les champs
d'édition) : avec beaucoup de matériels, afficher 5 <input> par ligne en
permanence rend la liste illisible et pousse le contenu hors de l'écran.
On ne dépense la largeur d'un vrai formulaire que sur la ligne qu'on
déplie. Voir aussi CLAUDE.md pour le contexte de ce choix.
#}
<ul class="liste-materiels">
{% for materiel in materiels %}
{% set sous_seuil = materiel.seuil_alerte is not none and materiel.quantite < materiel.seuil_alerte %}
<li>
<details class="ligne-materiel">
<summary>
<span class="noeud-chevron" aria-hidden="true"></span>
<span class="materiel-nom">{{ materiel.nom }}</span>
<span class="materiel-categorie">{{ materiel.categorie.chemin() }}</span>
<span class="materiel-code">{{ materiel.code_barre or "—" }}</span>
<span class="materiel-quantite {{ 'quantite-basse' if sous_seuil else '' }}">{{ materiel.quantite }}</span>
</summary>
<form method="post" action="/materiels/{{ materiel.id }}/modifier" class="formulaire-edition">
<label>Nom
<input type="text" name="nom" value="{{ materiel.nom }}" required>
</label>
<label>Catégorie
<select name="categorie_id" required>
{% for profondeur, categorie in categories_aplaties %}
<option value="{{ categorie.id }}" {{ "selected" if categorie.id == materiel.categorie_id else "" }}>
{{ "— " * profondeur }}{{ categorie.nom }}
</option>
{% endfor %}
</select>
</label>
<label>Code-barre
<input type="text" name="code_barre" value="{{ materiel.code_barre or '' }}">
</label>
<label>Quantité
<input type="number" name="quantite" value="{{ materiel.quantite }}" min="0" required>
</label>
<label>Seuil d'alerte
<input type="number" name="seuil_alerte" value="{{ materiel.seuil_alerte if materiel.seuil_alerte is not none else '' }}" min="0">
</label>
<div class="formulaire-actions">
<button type="submit">Enregistrer</button>
<button type="submit" formaction="/materiels/{{ materiel.id }}/supprimer" class="bouton-danger">Supprimer</button>
</div>
</form>
</details>
</li>
{% else %}
<li class="liste-vide">
{% if q %}Aucun matériel ne correspond à « {{ q }} ».{% else %}Aucun matériel pour l'instant.{% endif %}
</li>
{% endfor %}
</ul>
<h2>Ajouter un matériel</h2>
{% if categories_aplaties %}
<form method="post" action="/materiels" class="formulaire-grille">
<label>Nom <input type="text" name="nom" required></label>
<label>Catégorie
<select name="categorie_id" required>
{% for profondeur, categorie in categories_aplaties %}
<option value="{{ categorie.id }}">{{ "— " * profondeur }}{{ categorie.nom }}</option>
{% endfor %}
</select>
</label>
<label>Code-barre <input type="text" name="code_barre"></label>
<label>Quantité initiale <input type="number" name="quantite" value="0" min="0"></label>
<label>Seuil d'alerte <input type="number" name="seuil_alerte" min="0"></label>
<button type="submit">Créer</button>
</form>
{% else %}
<p>Créez d'abord une <a href="/categories">catégorie</a> avant d'ajouter un matériel.</p>
{% endif %}
{% endblock %}