Web-Development-with-Blazor.../Chapter13/MyBlog/Components/Pages/Admin/BlogPostEdit.razor
2023-02-17 15:28:17 +01:00

138 lines
4.1 KiB
Plaintext

@page "/admin/blogposts/new"
@page "/admin/blogposts/{Id}"
@inject IBlogApi _api
@inject NavigationManager _manager
@inject Components.Interfaces.IBrowserStorage _storage
@using Components.Interfaces
@inject IBlogNotificationService notificationService
@using Components.RazorComponents
@using Markdig;
<EditForm Model="Post" OnValidSubmit="SavePost">
<DataAnnotationsValidator />
<CustomCssClassProvider ProviderType="BootstrapFieldCssClassProvider" />
<BlogNavigationLock @ref="NavigationLock" />
<InputText @bind-Value="Post.Title" />
<ValidationMessage For="()=>Post.Title" />
<InputDate @bind-Value="Post.PublishDate" />
<ValidationMessage For="()=>Post.PublishDate" />
<InputSelect @bind-Value="selectedCategory">
<option value="0" disabled>None selected</option>
@foreach (var category in Categories)
{
<option value="@category.Id">@category.Name </option>
}
</InputSelect>
<ul>
@foreach (var tag in Tags)
{
<li>
@tag.Name
@if (Post.Tags.Any(t => t.Id == tag.Id))
{
<button type="button" @onclick="@(() => {Post.Tags.Remove(Post.Tags.Single(t=>t.Id==tag.Id)); })">Remove</button>
}
else
{
<button type="button" @onclick="@(()=> { Post.Tags.Add(tag); })">Add</button>
}
</li>
}
</ul>
<InputTextAreaOnInput @bind-Value="Post.Text" @onkeyup="UpdateHTMLAsync" />
<ValidationMessage For="()=>Post.Text" />
<button type="submit" class="btn btn-success">Save</button>
</EditForm>
@((MarkupString)markDownAsHTML)
@code{
[Parameter]
public string? Id { get; set; }
BlogPost Post { get; set; } = new();
List<Category> Categories { get; set; } = new();
List<Tag> Tags { get; set; } = new();
string? selectedCategory = null;
string? markDownAsHTML { get; set; }
BlogNavigationLock? NavigationLock { get; set; }
MarkdownPipeline pipeline = default!;
protected override Task OnInitializedAsync()
{
pipeline = new MarkdownPipelineBuilder()
.UseEmojiAndSmiley()
.Build();
return base.OnInitializedAsync();
}
protected async Task UpdateHTMLAsync()
{
if (Post.Text != null)
{
await notificationService.SendNotification(Post);
markDownAsHTML = Markdig.Markdown.ToHtml(Post.Text, pipeline);
if (string.IsNullOrEmpty(Post.Id))
{
await _storage.SetAsync("EditCurrentPost", Post);
}
}
}
bool hasTag(Tag tag)
{
return Post.Tags.Contains(tag);
}
protected override async Task OnParametersSetAsync()
{
if (Id != null)
{
var p = await _api.GetBlogPostAsync(Id);
if (p != null)
{
Post = p;
if (Post.Category != null)
{
selectedCategory = Post.Category.Id;
}
await UpdateHTMLAsync();
}
}
Categories = (await _api.GetCategoriesAsync())??new();
Tags = (await _api.GetTagsAsync())?? new();
base.OnParametersSet();
}
override protected async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender && string.IsNullOrEmpty(Id))
{
var saved = await _storage.GetAsync<BlogPost>("EditCurrentPost");
if (saved != null)
{
Post = saved;
StateHasChanged();
}
}
await base.OnAfterRenderAsync(firstRender);
}
public async Task SavePost()
{
if (!string.IsNullOrEmpty(selectedCategory) && Categories != null)
{
var category = Categories.FirstOrDefault(c => c.Id == selectedCategory);
if (category != null)
{
Post.Category = category;
}
}
await _api.SaveBlogPostAsync(Post);
NavigationLock?.CurrentEditContext.MarkAsUnmodified();
_manager.NavigateTo("/admin/blogposts");
}
}