@inject ServiceLivresApi Api @* Panneau de modification en lot, ouvert depuis la fiche série une fois des tomes cochés. ⚠️ Reprend le DESIGN de FormulaireLivre.razor (mêmes composants, même ordre de champs), mais chaque champ est précédé d'une case « Modifier… » : sans elle, la valeur par défaut d'un champ (« NonPrecise », « Physique »…) est déjà une vraie valeur, et l'appliquer à tous les livres sélectionnés écraserait un champ qu'on ne voulait pas toucher (CLAUDE.md, invariant 10). Un champ non coché ne s'affiche pas — c'est ce qui rend visible ce qui va être écrasé. *@

Les champs cochés remplacent la valeur existante sur chacun des @NombreLivres livres sélectionnés — pour les auteurs, une liste vide les retire tous.

@if (Saisie.ModifierType) {
@foreach (var type in Types) { }
}
@if (Saisie.ModifierThemes) { }
@if (Saisie.ModifierAuteurs) { @if (Saisie.Auteurs.Count > 1) {
@foreach (var role in Roles) { }
}
}
@if (Saisie.ModifierFormat) {
@foreach (var format in Formats) { }
}
@if (Saisie.ModifierEditeur) { }
@if (Saisie.ModifierStatut) { }
@if (!string.IsNullOrEmpty(Erreur)) { } @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(); private void PoserRole(int index, RoleAuteur role) => Saisie.Auteurs[index] = Saisie.Auteurs[index] with { Role = role }; /// Voir la remarque équivalente sur FormulaireLivre.razor : référence stable tant /// que la saisie ne change pas, sans quoi SaisieListe se remet à zéro à chaque frappe. private NomsAuteurs? _noms; private NomsAuteurs Noms => _noms ??= new NomsAuteurs(Saisie.Auteurs); private SaisieLot? _saisiePrecedente; private IReadOnlyList _themesConnus = []; protected override async Task OnInitializedAsync() { try { _themesConnus = [ .. (await Api.ListerAsync(new CritereLivres())) .SelectMany(l => l.Themes) .DistinctBy(NormalisationTexte.Normaliser, StringComparer.Ordinal) .OrderBy(NormalisationTexte.Normaliser, StringComparer.Ordinal), ]; } catch (Exception) { _themesConnus = []; } } protected override void OnParametersSet() { if (!ReferenceEquals(_saisiePrecedente, Saisie)) { _saisiePrecedente = Saisie; _noms = null; } } [Parameter, EditorRequired] public SaisieLot Saisie { get; set; } = new(); [Parameter] public int NombreLivres { get; set; } [Parameter] public string LibelleValidation { get; set; } = "Appliquer"; [Parameter] public string? Erreur { get; set; } [Parameter] public bool EnCours { get; set; } [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(); }