Auteurs cherchables et triables, filtre de prêt, rang dans les exports, couvertures d'envies

Auteurs
- Recherche et tri (par nom, ou du plus présent au moins présent), en mémoire : la liste
  est déjà chargée en entier — c'est elle qui sert l'instantané hors-ligne — et la filtrer
  côté serveur aurait rendu la page inutilisable sans réseau.
- Trois colonnes dont une seule est élastique : compteur à gauche sur une largeur figée,
  nom au milieu, actions à droite. Les compteurs et les boutons s'alignent alors d'une
  ligne à l'autre au lieu de suivre la longueur du nom.

Catalogue
- Filtre « À la maison / Prêtés », posé dans les deux implémentations (serveur et
  hors-ligne) et dans le test qui les confronte, avec un cas de prêt CLOS — c'est
  exactement là que les deux auraient pu diverger en silence.
- La ligne disparaît tant que rien n'est prêté, comme celles des formats et des types.

Envies
- ⚠️ Les couvertures manquaient parce que seul l'écran « ajouter une envie » remplissait
  CoverUrl : la bibliographie et les tomes manquants transmettent un ISBN mais aucune
  image. Le repli est posé à la LECTURE, donc il vaut aussi pour les envies déjà
  enregistrées, sans migration.
- Les exports .txt et .csv portent le rang d'envie. Le .txt en a le plus besoin : son
  groupement par auteur détruit précisément cet ordre.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
mathieu
2026-08-20 20:42:13 +02:00
co-authored by Claude Opus 5
parent 83089d7479
commit 4fd67e4e3b
13 changed files with 344 additions and 24 deletions
+16
View File
@@ -46,4 +46,20 @@ public record CritereLivres
/// <summary>Ne garder que les livres d'un auteur — le « cliquer sur un auteur » d'IDEES.md.</summary>
public int? AuteurId { get; init; }
/// <summary>
/// <c>true</c> = ce qui est dehors, <c>false</c> = ce qui est à la maison, <c>null</c> = tout.
/// </summary>
/// <remarks>
/// ⚠️ Contrairement à <see cref="Statut"/>, ce critère est <b>commun au foyer</b> : un prêt
/// n'appartient à personne en particulier, et aucune identité n'entre dans son évaluation.
/// C'est la même dissymétrie que partout ailleurs — le livre absent l'est pour tout le monde,
/// sa lecture ne l'est que pour soi.
/// <para>
/// L'écran « Prêts » répond déjà à « qu'est-ce qui est dehors ? ». Ce critère-ci répond à
/// l'autre moitié de la question, celle qu'aucun écran ne servait : « qu'est-ce que j'ai
/// réellement sous la main ? », par exemple avant de promettre un livre à quelqu'un.
/// </para>
/// </remarks>
public bool? Prete { get; init; }
}
+10
View File
@@ -54,6 +54,16 @@ public static class FiltreLivres
source = source.Where(l => l.Auteurs.Any(la => la.AuteurId == auteurId));
}
if (criteres.Prete is { } prete)
{
// Un prêt EN COURS est une ligne sans date de retour : l'historique clos ne compte
// pas. Aucune identité n'intervient — le prêt est commun au foyer, contrairement au
// statut de lecture juste au-dessus.
source = prete
? source.Where(l => l.Prets.Any(p => p.DateRetour == null))
: source.Where(l => !l.Prets.Any(p => p.DateRetour == null));
}
var terme = NormalisationTexte.Normaliser(criteres.Recherche);
if (terme.Length > 0)
{