@page "/auteurs" @inject ServiceLivresApi Api @inject EtatReseau Reseau @implements IDisposable MaBibli — auteurs

Auteurs

@if (_erreur is not null) { } @if (_suggestions is { Count: > 0 }) { @* Ce qui arrive ici est ce que la machine REFUSE de trancher. Les variantes sûres — casse, accents, ordre « Nom, Prénom », initiales abrégées — ont déjà été réunies à l'écriture et n'apparaissent jamais dans cette liste. Restent les cas ambigus, typiquement un patronyme seul face à un nom complet : deux personnes d'une même famille écrivent aussi des livres. *@

Rapprochements possibles

Ces noms se ressemblent sans qu'on puisse l'affirmer. Un patronyme seul peut désigner une autre personne de la même famille — à vous de trancher. Une fusion se défait mal.

} @if (_auteurs is null) {

Chargement…

} else if (_auteurs.Count == 0) {

Aucun auteur : la bibliothèque est vide.

} else {

@_auteurs.Count auteur@(_auteurs.Count > 1 ? "s" : "")

} @if (_collisionRenommage is not null) { } @code { private IReadOnlyList? _auteurs; private IReadOnlyList? _suggestions; private bool _enCours; private bool _renommageEnCours; private int? _auteurRenomme; private string _nomRenomme = string.Empty; private AuteurDto? _collisionRenommage; private string? _erreur; protected override void OnInitialized() => Reseau.Change += SurChangementReseau; private void SurChangementReseau() => _ = InvokeAsync(async () => { await ChargerAsync(); StateHasChanged(); }); public void Dispose() => Reseau.Change -= SurChangementReseau; /// Raison du blocage des fusions, ou null en ligne. private string? MotifBlocage => Reseau.EnLigne ? null : EtatReseau.MotifHorsLigne; protected override Task OnInitializedAsync() => ChargerAsync(); private static string Livres(int nombre) => $"{nombre} livre{(nombre > 1 ? "s" : "")}"; private async Task ChargerAsync() { _erreur = null; try { _auteurs = await Api.ListerAuteursAsync(); _suggestions = await Api.ListerRapprochementsAsync(); } catch (Exception ex) { _erreur = $"Impossible de charger les auteurs : {ex.Message}"; } } private Task AccepterAsync(SuggestionRapprochement suggestion) => DeciderAsync(() => Api.AccepterRapprochementAsync(suggestion.Source.Id, suggestion.Cible.Id)); private Task RefuserAsync(SuggestionRapprochement suggestion) => DeciderAsync(() => Api.RefuserRapprochementAsync(suggestion.Source.Id, suggestion.Cible.Id)); private void CommencerRenommage(AuteurDto auteur) { _auteurRenomme = auteur.Id; _nomRenomme = auteur.Nom; _collisionRenommage = null; _erreur = null; } private void AnnulerRenommage() { _auteurRenomme = null; _collisionRenommage = null; _nomRenomme = string.Empty; } private Task RenommerAsync() => EnvoyerRenommageAsync(false); private Task ConfirmerFusionAsync() => EnvoyerRenommageAsync(true); private async Task EnvoyerRenommageAsync(bool confirmerFusion) { if (_auteurRenomme is null || string.IsNullOrWhiteSpace(_nomRenomme)) { _erreur = "Le nom de l'auteur est obligatoire."; return; } _renommageEnCours = true; _erreur = null; var resultat = await Api.RenommerAuteurAsync( _auteurRenomme.Value, _nomRenomme, confirmerFusion); _renommageEnCours = false; if (resultat is null) { _erreur = "Le renommage n'a pas pu être enregistré."; return; } if (resultat.Collision is not null) { _collisionRenommage = resultat.Collision; return; } AnnulerRenommage(); await ChargerAsync(); } private async Task DeciderAsync(Func> action) { _enCours = true; var erreur = await action(); _enCours = false; if (erreur is not null) { _erreur = erreur; return; } // Une fusion peut en rendre d'autres caduques (l'un des deux noms disparaît) : on relit // la liste complète plutôt que de retirer la ligne traitée à la main. await ChargerAsync(); } }