Add edit feature

pull/3/head
Alexis Drai 2 years ago
parent 26664449fc
commit 6776ca6a0c

2
.gitignore vendored

@ -1,6 +1,8 @@
# Created by https://www.toptal.com/developers/gitignore/api/dotnetcore,visualstudio,visualstudiocode
# Edit at https://www.toptal.com/developers/gitignore?templates=dotnetcore,visualstudio,visualstudiocode
/wwwroot/images/*.png
### DotnetCore ###
# .NET Core build folders
bin/

@ -0,0 +1,48 @@
using blazor_lab.Models;
namespace blazor_lab.Factories
{
public static class ItemFactory
{
public static ItemModel ToModel(Item item, byte[] imageContent)
{
return new ItemModel
{
Id = item.Id,
DisplayName = item.DisplayName,
Name = item.Name,
RepairWith = item.RepairWith,
EnchantCategories = item.EnchantCategories,
MaxDurability = item.MaxDurability,
StackSize = item.StackSize,
ImageContent = imageContent
};
}
public static Item Create(ItemModel model)
{
return new Item
{
Id = model.Id,
DisplayName = model.DisplayName,
Name = model.Name,
RepairWith = model.RepairWith,
EnchantCategories = model.EnchantCategories,
MaxDurability = model.MaxDurability,
StackSize = model.StackSize,
CreatedDate = DateTime.Now
};
}
public static void Update(Item item, ItemModel model)
{
item.DisplayName = model.DisplayName;
item.Name = model.Name;
item.RepairWith = model.RepairWith;
item.EnchantCategories = model.EnchantCategories;
item.MaxDurability = model.MaxDurability;
item.StackSize = model.StackSize;
item.UpdatedDate = DateTime.Now;
}
}
}

@ -0,0 +1,89 @@
@page "/edit/{Id:int}"
<h3>Edit</h3>
<EditForm Model="@itemModel" OnValidSubmit="@HandleValidSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
<p>
<label for="display-name">
Display name:
<InputText id="display-name" @bind-Value="itemModel.DisplayName" />
</label>
</p>
<p>
<label for="name">
Name:
<InputText id="name" @bind-Value="itemModel.Name" />
</label>
</p>
<p>
<label for="stack-size">
Stack size:
<InputNumber id="stack-size" @bind-Value="itemModel.StackSize" />
</label>
</p>
<p>
<label for="max-durability">
Max durability:
<InputNumber id="max-durability" @bind-Value="itemModel.MaxDurability" />
</label>
</p>
<p>
Enchant categories:
<div>
@foreach (var enchant in enchantCategories)
{
<label>
<input type="checkbox"
checked="@(itemModel.EnchantCategories.Contains(enchant) ? "checked" : null)"
@onchange="@(e => OnEnchantCategoriesChange(enchant, e.Value))" />
@enchant
</label>
}
</div>
</p>
<p>
Repair with:
<div>
@foreach (var material in repairWith)
{
<label>
<input type="checkbox"
checked="@(itemModel.EnchantCategories.Contains(material) ? "checked" : null)"
@onchange="@(e => OnRepairWithChange(material, e.Value))" />
@material
</label>
}
</div>
</p>
<p>
<label>
Current Item image:
@if (File.Exists($"{WebHostEnvironment.WebRootPath}/images/{itemModel.Name}.png"))
{
<img src="images/@(itemModel.Name).png" class="img-thumbnail" title="@itemModel.DisplayName" alt="@itemModel.DisplayName" style="max-width: 150px" />
}
else
{
<img src="images/default.png" class="img-thumbnail" title="@itemModel.DisplayName" alt="@itemModel.DisplayName" style="max-width: 150px" />
}
</label>
</p>
<p>
<label>
Item image:
<InputFile OnChange="@LoadImage" accept=".png" />
</label>
</p>
<p>
<label>
Accept Condition:
<InputCheckbox @bind-Value="itemModel.AcceptConditions" />
</label>
</p>
<button type="submit">Submit</button>
</EditForm>

@ -0,0 +1,116 @@
using blazor_lab.Factories;
using blazor_lab.Models;
using blazor_lab.Services;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
namespace blazor_lab.Pages
{
public partial class Edit
{
[Parameter]
public int Id { get; set; }
/// <summary>
/// The default enchant categories.
/// </summary>
private readonly List<string> enchantCategories = new() { "armor", "armor_head", "armor_chest", "weapon", "digger", "breakable", "vanishable" };
/// <summary>
/// The current item model
/// </summary>
private ItemModel itemModel = new()
{
EnchantCategories = new List<string>(),
RepairWith = new List<string>()
};
/// <summary>
/// The default repair with.
/// </summary>
private readonly List<string> repairWith = new() { "oak_planks", "spruce_planks", "birch_planks", "jungle_planks", "acacia_planks", "dark_oak_planks", "crimson_planks", "warped_planks" };
[Inject]
public IDataService DataService { get; set; }
[Inject]
public NavigationManager NavigationManager { get; set; }
[Inject]
public IWebHostEnvironment WebHostEnvironment { get; set; }
protected override async Task OnInitializedAsync()
{
var item = await DataService.GetById(Id);
byte[] fileContent;
if (File.Exists($"{WebHostEnvironment.WebRootPath}/images/{itemModel.Name}.png"))
{
fileContent = await File.ReadAllBytesAsync($"{WebHostEnvironment.WebRootPath}/images/{item.Name}.png");
}
else
{
fileContent = await File.ReadAllBytesAsync($"{WebHostEnvironment.WebRootPath}/images/default.png");
}
// Set the model with the item
itemModel = ItemFactory.ToModel(item, fileContent);
}
private async Task HandleValidSubmit()
{
await DataService.Update(Id, itemModel);
NavigationManager.NavigateTo("list");
}
private async Task LoadImage(InputFileChangeEventArgs e)
{
// Set the content of the image to the model
using (var memoryStream = new MemoryStream())
{
await e.File.OpenReadStream().CopyToAsync(memoryStream);
itemModel.ImageContent = memoryStream.ToArray();
}
}
private void OnEnchantCategoriesChange(string item, object checkedValue)
{
if ((bool)checkedValue)
{
if (!itemModel.EnchantCategories.Contains(item))
{
itemModel.EnchantCategories.Add(item);
}
return;
}
if (itemModel.EnchantCategories.Contains(item))
{
itemModel.EnchantCategories.Remove(item);
}
}
private void OnRepairWithChange(string item, object checkedValue)
{
if ((bool)checkedValue)
{
if (!itemModel.RepairWith.Contains(item))
{
itemModel.RepairWith.Add(item);
}
return;
}
if (itemModel.RepairWith.Contains(item))
{
itemModel.RepairWith.Remove(item);
}
}
}
}

@ -50,7 +50,13 @@
Caption="Created on"
DisplayFormat="{0:d}"
DisplayFormatProvider="@System.Globalization.CultureInfo.GetCultureInfo("fr-FR")" />
<DataGridColumn TItem="Item" Field="@nameof(Item.Id)" Caption="Action">
<DisplayTemplate>
<a href="edit/@(context.Id)" class="btn btn-primary">
<i class="fa fa-edit" /> Editer
</a>
</DisplayTemplate>
</DataGridColumn>
</DataGrid>
}

@ -1,4 +1,5 @@
using blazor_lab.Models;
using blazor_lab.Factories;
using blazor_lab.Models;
using Blazored.LocalStorage;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Hosting;
@ -29,26 +30,16 @@ namespace blazor_lab.Services
pathToFakeData = $"{_navigationManager.BaseUri}fake-data.json";
}
public async Task Add(ItemModel itemModel)
public async Task Add(ItemModel model)
{
// Get the current data
var currentData = await _localStorageService.GetItemAsync<List<Item>>("data");
// Simulate the Id
itemModel.Id = currentData.Max(item => item.Id) + 1;
model.Id = currentData.Max(item => item.Id) + 1;
// Add the item to the current data
currentData.Add(new Item
{
Id = itemModel.Id,
DisplayName = itemModel.DisplayName,
Name = itemModel.Name,
RepairWith = itemModel.RepairWith,
EnchantCategories = itemModel.EnchantCategories,
MaxDurability = itemModel.MaxDurability,
StackSize = itemModel.StackSize,
CreatedDate = DateTime.Now
});
currentData.Add(ItemFactory.Create(model));
// Save the image
var imagePathInfo = new DirectoryInfo($"{_webHostEnvironment.WebRootPath}/images");
@ -60,10 +51,10 @@ namespace blazor_lab.Services
}
// Determine the image name
var fileName = new FileInfo($"{imagePathInfo}/{itemModel.Name}.png");
var fileName = new FileInfo($"{imagePathInfo}/{model.Name}.png");
// Write the file content
await File.WriteAllBytesAsync(fileName.FullName, itemModel.ImageContent);
await File.WriteAllBytesAsync(fileName.FullName, model.ImageContent);
// Save the data
await _localStorageService.SetItemAsync("data", currentData);
@ -83,6 +74,18 @@ namespace blazor_lab.Services
return (await _localStorageService.GetItemAsync<Item[]>("data")).Length;
}
public async Task<Item> GetById(int id)
{
var item = (await _localStorageService.GetItemAsync<List<Item>>("data")).FirstOrDefault(w => w.Id == id);
if (item == null)
{
throw new FileNotFoundException($"could not find item #{id}");
}
return item;
}
public async Task<List<Item>> List(int currentPage, int pageSize)
{
if (await _localStorageService.GetItemAsync<Item[]>("data") == null)
@ -95,5 +98,30 @@ namespace blazor_lab.Services
return (await _localStorageService.GetItemAsync<Item[]>("data")).Skip((currentPage - 1) * pageSize).Take(pageSize).ToList();
}
public async Task Update(int id, ItemModel model)
{
var currentData = await _localStorageService.GetItemAsync<List<Item>>("data");
var item = await GetById(id);
var imagePathInfo = new DirectoryInfo($"{_webHostEnvironment.WebRootPath}/images");
if (!imagePathInfo.Exists)
{
imagePathInfo.Create();
}
if (item.Name != model.Name)
{
var oldFileName = new FileInfo($"{imagePathInfo}/{item.Name}.png");
if (oldFileName.Exists)
{
File.Delete(oldFileName.FullName);
}
}
var fileName = new FileInfo($"{imagePathInfo}/{model.Name}.png");
await File.WriteAllBytesAsync(fileName.FullName, model.ImageContent);
ItemFactory.Update(item, model);
await _localStorageService.SetItemAsync("data", currentData);
}
}
}

@ -7,5 +7,7 @@ namespace blazor_lab.Services
Task Add(ItemModel itemModel);
Task<int> Count();
Task<List<Item>> List(int currentPage, int pageSize);
Task<Item> GetById(int id);
Task Update(int id, ItemModel model);
}
}

Loading…
Cancel
Save