@*
Formulaire d'une fiche livre, partagé par l'ajout (ISBN ou manuel) et l'édition.
Le pré-remplissage par ISBN est une AIDE, pas une contrainte : tous les champs restent
modifiables, et une fiche incomplète peut toujours être complétée à la main (CLAUDE.md).
*@
}
@*
⚠️ L'ORDRE DES CHAMPS EST UNE DÉCISION (lot Q, 2026-08-21), pas une mise en page.
Type de document, puis thèmes, puis auteurs, puis rôles : c'est l'ordre dans lequel on
regarde un livre qu'on tient en main, et surtout le type COMMANDE LA SUITE de la saisie —
les rôles ne se posent que là. Relégué en bas, il obligeait à descendre tout le formulaire
pour dire « c'est une BD », c'est-à-dire après avoir saisi ce qui en dépend.
⚠️ Remonter le champ le rend visible ; le PRÉREMPLIR écrirait quelque chose de faux. Le
défaut reste « non précisé », qui ne prétend rien (décision actée) — c'est aussi ce qui
rend l'étiquette honnête dans les listes : elle ne s'affiche que si un type a été choisi.
*@
@*
Un seul champ, plusieurs auteurs : le point-virgule les sépare. La virgule est déjà
prise par la forme bibliographique « Zola, Émile », qu'on doit pouvoir taper telle quelle.
Le serveur rapproche ensuite les variantes sûres d'un auteur déjà connu.
*@
@*
Les rôles n'apparaissent qu'à partir de DEUX auteurs, et c'est délibéré : un roman n'a
qu'un signataire dont le rôle ne se pose pas, et une ligne de boutons sous chaque saisie
n'apprendrait rien. La question « qui écrit, qui dessine ? » ne se pose qu'à plusieurs.
Le défaut reste « non précisé » : on ne remplit pas une case à la place de l'utilisateur.
*@
@if (Saisie.Auteurs.Count > 1)
{
}
@*
Le format n'est plus affiché dans les listes que pour les ebooks : un livre y est donc
physique par défaut. Cette valeur DOIT rester présélectionnée ici, sinon on créerait
des fiches sans format en croyant que « rien d'affiché = physique ».
C'est le cas sans code particulier : Format.Physique vaut 0, valeur par défaut de
l'énumération, et le segment correspondant est donc actif dès l'ouverture.
*@
@if (!string.IsNullOrEmpty(Erreur))
{
@Erreur
}
@* Un enregistrement impossible se dit AVANT le clic : un bouton qui échoue en silence est
pire que pas de bouton du tout (CLAUDE.md, stratégie hors-ligne). *@
@if (!string.IsNullOrEmpty(MessageBlocage))
{
@MessageBlocage
}
@if (OnAnnuler.HasDelegate)
{
}
@code {
private static readonly Format[] Formats = Enum.GetValues();
private static readonly TypeDocument[] Types = Enum.GetValues();
private static readonly RoleAuteur[] Roles = Enum.GetValues();
///
/// Pose le rôle d'un auteur.
///
///
/// est un record : on remplace l'entrée plutôt que de la muter,
/// et la liste reste celle que la propriété Auteur saura relire pour préserver les
/// rôles à la frappe suivante.
///
private void PoserRole(int index, RoleAuteur role) =>
Saisie.Auteurs[index] = Saisie.Auteurs[index] with { Role = role };
[Parameter, EditorRequired] public EnregistrementLivre Saisie { get; set; } = new();
[Parameter] public string LibelleValidation { get; set; } = "Enregistrer";
[Parameter] public string? Erreur { get; set; }
[Parameter] public bool EnCours { get; set; }
///
/// Raison pour laquelle l'enregistrement est impossible (typiquement l'absence de réseau).
/// Renseignée, elle désactive la validation et s'affiche : la saisie reste lisible, mais
/// l'utilisateur sait pourquoi il ne peut pas valider.
///
[Parameter] public string? MessageBlocage { get; set; }
private bool Bloque => !string.IsNullOrEmpty(MessageBlocage);
[Parameter] public EventCallback OnValider { get; set; }
[Parameter] public EventCallback OnAnnuler { get; set; }
private Task Valider() => OnValider.InvokeAsync();
}