MaBibli 1.0.0
Gestion de bibliothèque personnelle auto-hébergée : catalogue, prêts, scan de code-barres, consultation hors-ligne. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
@page "/souhaits/revues/{Id:int}/edition"
|
||||
@inject ServiceLivresApi Api
|
||||
@inject EtatReseau Reseau
|
||||
@inject NavigationManager Navigation
|
||||
@implements IDisposable
|
||||
|
||||
@*
|
||||
Le même geste que pour une envie de livre, sur la table sœur : écran dédié, mode dans
|
||||
l'adresse. Les deux formulaires ne se fondent pas en un seul — une revue n'a ni auteur, ni
|
||||
éditeur, ni ISBN, et un formulaire à moitié grisé se lit plus mal que deux formulaires courts.
|
||||
*@
|
||||
|
||||
<PageTitle>MaBibli — modifier une envie de revue</PageTitle>
|
||||
|
||||
<h1 class="titre-page">Modifier une envie de revue</h1>
|
||||
|
||||
@if (_erreur is not null)
|
||||
{
|
||||
<p class="message-erreur" role="alert">@_erreur</p>
|
||||
}
|
||||
|
||||
@if (_introuvable)
|
||||
{
|
||||
<p class="message-discret">
|
||||
@(Reseau.EnLigne
|
||||
? "Cette envie n'existe plus dans votre liste."
|
||||
: "Cette envie n'est pas dans les données enregistrées sur cet appareil.")
|
||||
</p>
|
||||
}
|
||||
else if (_saisie is null)
|
||||
{
|
||||
<Patience Message="Ouverture de l'envie…" />
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="formulaire">
|
||||
<label class="champ">
|
||||
<span class="champ-libelle">Titre de la revue <span class="obligatoire" aria-hidden="true">*</span></span>
|
||||
<input class="champ-saisie" type="text" @bind="_saisie.Titre" @bind:event="oninput"
|
||||
placeholder="Médor" autocomplete="off" />
|
||||
</label>
|
||||
|
||||
<label class="champ">
|
||||
<span class="champ-libelle">
|
||||
Numéro <span class="champ-aide">(vide = la revue entière)</span>
|
||||
</span>
|
||||
<input class="champ-saisie" type="text" @bind="_saisie.Numero" @bind:event="oninput"
|
||||
placeholder="43, hors-série 7…" autocomplete="off" />
|
||||
</label>
|
||||
|
||||
@* La saisie garde ce qui est tapé : le tiret est posé à l'enregistrement, jamais à la
|
||||
frappe — sinon il se battrait avec le curseur. *@
|
||||
<label class="champ">
|
||||
<span class="champ-libelle">ISSN <span class="champ-aide">(facultatif)</span></span>
|
||||
<input class="champ-saisie" type="text" @bind="_saisie.Issn" @bind:event="oninput"
|
||||
placeholder="2466-6718" autocomplete="off" />
|
||||
</label>
|
||||
|
||||
<label class="champ">
|
||||
<span class="champ-libelle">Note</span>
|
||||
<input class="champ-saisie" type="text" @bind="_saisie.Note" @bind:event="oninput"
|
||||
placeholder="« vu chez le dentiste »…" autocomplete="off" />
|
||||
</label>
|
||||
|
||||
@if (!Reseau.EnLigne)
|
||||
{
|
||||
<p class="message-avertissement" role="status">@EtatReseau.MotifHorsLigne</p>
|
||||
}
|
||||
|
||||
<div class="actions-formulaire">
|
||||
<button type="button" class="bouton bouton-principal"
|
||||
disabled="@(_enCours || !Reseau.EnLigne || string.IsNullOrWhiteSpace(_saisie.Titre))"
|
||||
title="@MotifBlocage" @onclick="EnregistrerAsync">
|
||||
@(_enCours ? "Enregistrement…" : "Enregistrer")
|
||||
</button>
|
||||
|
||||
<a class="bouton bouton-discret" href="souhaits">Annuler</a>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@code {
|
||||
[Parameter] public int Id { get; set; }
|
||||
|
||||
private EnregistrementRevueSouhaitee? _saisie;
|
||||
private bool _introuvable;
|
||||
private bool _enCours;
|
||||
private string? _erreur;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
Reseau.Change += SurChangementReseau;
|
||||
await ChargerAsync();
|
||||
}
|
||||
|
||||
private void SurChangementReseau() => _ = InvokeAsync(StateHasChanged);
|
||||
|
||||
public void Dispose() => Reseau.Change -= SurChangementReseau;
|
||||
|
||||
private string? MotifBlocage => Reseau.EnLigne ? null : EtatReseau.MotifHorsLigne;
|
||||
|
||||
private async Task ChargerAsync()
|
||||
{
|
||||
var envies = await Api.ListerRevuesSouhaiteesAsync();
|
||||
var envie = envies.FirstOrDefault(e => e.Id == Id);
|
||||
|
||||
if (envie is null)
|
||||
{
|
||||
_introuvable = true;
|
||||
return;
|
||||
}
|
||||
|
||||
_saisie = new EnregistrementRevueSouhaitee
|
||||
{
|
||||
Titre = envie.Titre,
|
||||
Numero = envie.Numero,
|
||||
Issn = envie.Issn,
|
||||
Note = envie.Note,
|
||||
};
|
||||
}
|
||||
|
||||
private async Task EnregistrerAsync()
|
||||
{
|
||||
if (_saisie is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_enCours = true;
|
||||
_erreur = null;
|
||||
|
||||
var resultat = await Api.ModifierRevueSouhaiteeAsync(Id, _saisie);
|
||||
|
||||
_enCours = false;
|
||||
|
||||
if (!resultat.EstOk)
|
||||
{
|
||||
_erreur = resultat.Erreur;
|
||||
return;
|
||||
}
|
||||
|
||||
Navigation.NavigateTo("souhaits");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user