Rien n'empêchait de rescanner un livre déjà catalogué. Plutôt qu'un index unique — qui interdirait le second exemplaire, cas parfaitement légitime — la création répond 409 avec les fiches semblables, et « confirmerDoublon » enregistre la même saisie. Deux critères, dont aucun n'est une clé : ISBN identique, ou clé d'œuvre et auteur communs. La clé d'œuvre étant un préfixe de TitreNormalise, SQL dégrossit sur la colonne indexée et l'égalité exacte se vérifie ensuite en mémoire. Vérifié en exécution : avertissement, retour au formulaire intact, et ajout confirmé créant bien un second exemplaire. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
86 lines
2.6 KiB
Plaintext
86 lines
2.6 KiB
Plaintext
@page "/ajout/manuel"
|
|
@inject ServiceLivresApi Api
|
|
@inject NavigationManager Navigation
|
|
@inject EtatReseau Reseau
|
|
@implements IDisposable
|
|
|
|
<PageTitle>MaBibli — saisie manuelle</PageTitle>
|
|
|
|
<h1 class="titre-page">Saisie manuelle</h1>
|
|
|
|
<p class="message-discret">
|
|
Pour les livres sans ISBN, ou dont aucune notice ne convient. L'ISBN reste facultatif.
|
|
</p>
|
|
|
|
@*
|
|
Le formulaire s'efface pendant qu'on tranche le doublon : la saisie n'est pas perdue pour
|
|
autant, elle attend dans « _saisie » et revient telle quelle si l'on renonce. Laisser les
|
|
deux à l'écran donnerait deux boutons d'ajout, dont un seul confirme.
|
|
*@
|
|
@if (_doublons is { } doublons)
|
|
{
|
|
<AvertissementDoublon Doublons="doublons"
|
|
EnCours="_enregistrement"
|
|
OnConfirmer="ConfirmerAsync"
|
|
OnRenoncer="() => _doublons = null" />
|
|
}
|
|
else
|
|
{
|
|
<FormulaireLivre Saisie="_saisie"
|
|
LibelleValidation="Ajouter au catalogue"
|
|
Erreur="@_erreur"
|
|
EnCours="_enregistrement"
|
|
MessageBlocage="@(Reseau.EnLigne ? null : EtatReseau.MotifHorsLigne)"
|
|
OnValider="EnregistrerAsync"
|
|
OnAnnuler="Retour" />
|
|
}
|
|
|
|
@code {
|
|
private readonly EnregistrementLivre _saisie = new();
|
|
|
|
protected override void OnInitialized() => Reseau.Change += SurChangementReseau;
|
|
|
|
private void SurChangementReseau() => _ = InvokeAsync(StateHasChanged);
|
|
|
|
public void Dispose() => Reseau.Change -= SurChangementReseau;
|
|
|
|
private bool _enregistrement;
|
|
private string? _erreur;
|
|
private DoublonsLivre? _doublons;
|
|
|
|
private Task EnregistrerAsync() => AjouterAsync(false);
|
|
|
|
/// <summary>Ajout maintenu après avoir vu ce que le catalogue contenait déjà.</summary>
|
|
private Task ConfirmerAsync() => AjouterAsync(true);
|
|
|
|
private async Task AjouterAsync(bool confirmerDoublon)
|
|
{
|
|
_enregistrement = true;
|
|
_erreur = null;
|
|
|
|
var resultat = await Api.CreerAsync(_saisie, confirmerDoublon);
|
|
|
|
_enregistrement = false;
|
|
|
|
// Un doublon signalé n'est pas un échec : rien n'a été écrit, et la même saisie
|
|
// confirmée s'enregistrera telle quelle.
|
|
if (resultat.Doublons is { } doublons)
|
|
{
|
|
_doublons = doublons;
|
|
return;
|
|
}
|
|
|
|
_doublons = null;
|
|
|
|
if (!resultat.EstOk)
|
|
{
|
|
_erreur = resultat.Erreur;
|
|
return;
|
|
}
|
|
|
|
Navigation.NavigateTo("/");
|
|
}
|
|
|
|
private void Retour() => Navigation.NavigateTo("/");
|
|
}
|