ajout de razor components et debut de api

master
Chloé MOURGAND 2 years ago
parent a4505cc81c
commit f4b567e8c2

@ -0,0 +1,6 @@
@typeparam TItem
<div class="card text-center">
@CardHeader(Item)
@CardBody(Item)
@CardFooter
</div>

@ -0,0 +1,19 @@
using Microsoft.AspNetCore.Components;
namespace MyFirstBlazor.Components
{
public partial class Card<TItem>
{
[Parameter]
public RenderFragment<TItem> CardBody { get; set; }
[Parameter]
public RenderFragment CardFooter { get; set; }
[Parameter]
public RenderFragment<TItem> CardHeader { get; set; }
[Parameter]
public TItem Item { get; set; }
}
}

@ -0,0 +1,51 @@
<CascadingValue Value="@this">
<div class="container">
<div class="row">
<div class="col-6">
<div>Available items:</div>
<div>
<div class="css-grid">
@foreach (var item in Items)
{
<CraftingItem Item="item" NoDrop="true"/>
}
</div>
</div>
</div>
<div class="col-6">
<div>Recipe</div>
<div>
<div class="css-recipe">
<CraftingItem Index="0"/>
<CraftingItem Index="1"/>
<CraftingItem Index="2"/>
<CraftingItem Index="3"/>
<CraftingItem Index="4"/>
<CraftingItem Index="5"/>
<CraftingItem Index="6"/>
<CraftingItem Index="7"/>
<CraftingItem Index="8"/>
</div>
</div>
<div>Result</div>
<div>
<CraftingItem Item="RecipeResult"/>
</div>
</div>
<div class="col-12">
<div>Actions</div>
<div class="actions" id="actions">
</div>
</div>
</div>
</div>
</CascadingValue>

@ -0,0 +1,81 @@
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using MyFirstBlazor.Models;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
namespace MyFirstBlazor.Components
{
public partial class Crafting
{
private Item _recipeResult;
public Crafting()
{
Actions = new ObservableCollection<CraftingAction>();
Actions.CollectionChanged += OnActionsCollectionChanged;
this.RecipeItems = new List<Item> { null, null, null, null, null, null, null, null, null };
}
public ObservableCollection<CraftingAction> Actions { get; set; }
public Item CurrentDragItem { get; set; }
[Parameter]
public List<Item> Items { get; set; }
public List<Item> RecipeItems { get; set; }
public Item RecipeResult
{
get => this._recipeResult;
set
{
if (this._recipeResult == value)
{
return;
}
this._recipeResult = value;
this.StateHasChanged();
}
}
[Parameter]
public List<CraftingRecipe> Recipes { get; set; }
/// <summary>
/// Gets or sets the java script runtime.
/// </summary>
[Inject]
internal IJSRuntime JavaScriptRuntime { get; set; }
public void CheckRecipe()
{
RecipeResult = null;
// Get the current model
var currentModel = string.Join("|", this.RecipeItems.Select(s => s != null ? s.Name : string.Empty));
this.Actions.Add(new CraftingAction { Action = $"Items : {currentModel}" });
foreach (var craftingRecipe in Recipes)
{
// Get the recipe model
var recipeModel = string.Join("|", craftingRecipe.Have.SelectMany(s => s));
this.Actions.Add(new CraftingAction { Action = $"Recipe model : {recipeModel}" });
if (currentModel == recipeModel)
{
RecipeResult = craftingRecipe.Give;
}
}
}
private void OnActionsCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
{
JavaScriptRuntime.InvokeVoidAsync("Crafting.AddActions", e.NewItems);
}
}
}

@ -0,0 +1,19 @@
.css-grid {
grid-template-columns: repeat(4,minmax(0,1fr));
gap: 10px;
display: grid;
width: 286px;
}
.css-recipe {
grid-template-columns: repeat(3,minmax(0,1fr));
gap: 10px;
display: grid;
width: 212px;
}
.actions {
border: 1px solid black;
height: 250px;
overflow: scroll;
}

@ -0,0 +1,16 @@
window.Crafting =
{
AddActions: function (data) {
data.forEach(element => {
var div = document.createElement('div');
div.innerHTML = 'Action: ' + element.action + ' - Index: ' + element.index;
if (element.item) {
div.innerHTML += ' - Item Name: ' + element.item.name;
}
document.getElementById('actions').appendChild(div);
});
}
}

@ -0,0 +1,11 @@
using MyFirstBlazor.Models;
namespace MyFirstBlazor.Components
{
public class CraftingAction
{
public string Action { get; set; }
public int Index { get; set; }
public Item Item { get; set; }
}
}

@ -0,0 +1,13 @@
<div class="item"
ondragover="event.preventDefault();"
draggable="true"
@ondragstart="@OnDragStart"
@ondrop="@OnDrop"
@ondragenter="@OnDragEnter"
@ondragleave="@OnDragLeave">
@if (Item != null)
{
@Item.DisplayName
}
</div>

@ -0,0 +1,66 @@
using Blazorise;
using Microsoft.AspNetCore.Components;
using MyFirstBlazor.Models;
namespace MyFirstBlazor.Components
{
public partial class CraftingItem
{
[Parameter]
public int Index { get; set; }
[Parameter]
public Item Item { get; set; }
[Parameter]
public bool NoDrop { get; set; }
[CascadingParameter]
public Crafting Parent { get; set; }
internal void OnDragEnter()
{
if (NoDrop)
{
return;
}
Parent.Actions.Add(new CraftingAction { Action = "Drag Enter", Item = this.Item, Index = this.Index });
}
internal void OnDragLeave()
{
if (NoDrop)
{
return;
}
Parent.Actions.Add(new CraftingAction { Action = "Drag Leave", Item = this.Item, Index = this.Index });
}
internal void OnDrop()
{
if (NoDrop)
{
return;
}
this.Item = Parent.CurrentDragItem;
Parent.RecipeItems[this.Index] = this.Item;
Parent.Actions.Add(new CraftingAction { Action = "Drop", Item = this.Item, Index = this.Index });
// Check recipe
Parent.CheckRecipe();
}
private void OnDragStart()
{
Parent.CurrentDragItem = this.Item;
Parent.Actions.Add(new CraftingAction { Action = "Drag Start", Item = this.Item, Index = this.Index });
}
}
}

@ -0,0 +1,6 @@
.item {
width: 64px;
height: 64px;
border: 1px solid;
overflow: hidden;
}

@ -0,0 +1,9 @@
using MyFirstBlazor.Models;
namespace MyFirstBlazor.Components
{
public class CraftingRecipe
{
public Item Give { get; set; }
public List<List<string>> Have { get; set; }
}
}

@ -0,0 +1,12 @@
@typeparam TItem
<div>
@if ((Items?.Count ?? 0) != 0)
{
@foreach (var item in Items)
{
@ShowTemplate(item)
;
}
}
</div>

@ -0,0 +1,13 @@
using Microsoft.AspNetCore.Components;
namespace MyFirstBlazor.Components
{
public partial class ShowItems<TItem>
{
[Parameter]
public List<TItem> Items { get; set; }
[Parameter]
public RenderFragment<TItem> ShowTemplate { get; set; }
}
}

@ -0,0 +1,9 @@
namespace MyFirstBlazor.Models
{
public class Cake
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Cost { get; set; }
}
}

@ -11,5 +11,6 @@
public List<string> RepairWith { get; set; }
public DateTime CreatedDate { get; set; }
public DateTime? UpdatedDate { get; set; }
public string ImageBase64 { get; set; }
}
}

@ -33,5 +33,8 @@ namespace MyFirstBlazor.Models
[Required(ErrorMessage = "The image of the item is mandatory!")]
public byte[] ImageContent { get; set; }
public string ImageBase64 { get; set; }
}
}

@ -1,5 +1,7 @@
@page "/"
@using System.Globalization
@using MyFirstBlazor.Components;
@using MyFirstBlazor.Models;
<PageTitle>Index</PageTitle>
@ -15,4 +17,8 @@ Welcome to your new app.
<br />
<SurveyPrompt Title="How is Blazor working for you?" />
<div>
<Crafting Items="Items" Recipes="Recipes" />
</div>

@ -0,0 +1,53 @@
using Microsoft.AspNetCore.Components;
using MyFirstBlazor.Components;
using MyFirstBlazor.Models;
using MyFirstBlazor.Services;
namespace MyFirstBlazor.Pages
{
public partial class Index
{
[Inject]
public IDataService DataService { get; set; }
public List<Item> Items { get; set; } = new List<Item>();
private List<CraftingRecipe> Recipes { get; set; } = new List<CraftingRecipe>();
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
Items = await DataService.List(0, await DataService.Count());
Recipes = await DataService.GetRecipes();
if(firstRender) StateHasChanged();
await base.OnAfterRenderAsync(firstRender);
}
public List<Cake> Cakes { get; set; }
//protected override Task OnAfterRenderAsync(bool firstRender)
//{
// LoadCakes();
// StateHasChanged();
// return base.OnAfterRenderAsync(firstRender);
//}
public void LoadCakes()
{
Cakes = new List<Cake>
{
// items hidden for display purpose
new Cake
{
Id = 1,
Name = "Red Velvet",
Cost = 60
},
};
}
}
}

@ -28,6 +28,7 @@
</div>
<script src="_framework/blazor.server.js"></script>
<script src="Components/Crafting.razor.js"></script>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css">
<link href="_content/Blazorise/blazorise.css" rel="stylesheet" />

@ -1,5 +1,6 @@
using Blazored.LocalStorage;
using Microsoft.AspNetCore.Components;
using MyFirstBlazor.Components;
using MyFirstBlazor.Factories;
using MyFirstBlazor.Models;
@ -26,14 +27,6 @@ namespace MyFirstBlazor.Services
public async Task Add(ItemModel model)
{
// Get the current data
var currentData = await _localStorage.GetItemAsync<List<Item>>("data");
// Simulate the Id
model.Id = currentData.Max(s => s.Id) + 1;
// Add the item to the current data
currentData.Add(ItemFactory.Create(model));
// Save the image
var imagePathInfo = new DirectoryInfo($"{_webHostEnvironment.WebRootPath}/images");
@ -50,10 +43,6 @@ namespace MyFirstBlazor.Services
// Write the file content
await File.WriteAllBytesAsync(fileName.FullName, model.ImageContent);
// Save the data
await _localStorage.SetItemAsync("data", currentData);
}
public async Task<int> Count()
@ -95,17 +84,9 @@ namespace MyFirstBlazor.Services
public async Task Update(int id, ItemModel model)
{
// Get the current data
var currentData = await _localStorage.GetItemAsync<List<Item>>("data");
// Get the item int the list
var item = currentData.FirstOrDefault(w => w.Id == id);
// Check if item exist
if (item == null)
{
throw new Exception($"Unable to found the item with ID: {id}");
}
// Save the image
var imagePathInfo = new DirectoryInfo($"{_webHostEnvironment.WebRootPath}/images");
@ -115,7 +96,6 @@ namespace MyFirstBlazor.Services
{
imagePathInfo.Create();
}
// Delete the previous image
if (item.Name != model.Name)
{
@ -133,11 +113,8 @@ namespace MyFirstBlazor.Services
// Write the file content
await File.WriteAllBytesAsync(fileName.FullName, model.ImageContent);
// Modify the content of the item
ItemFactory.Update(item, model);
// Save the data
await _localStorage.SetItemAsync("data", currentData);
}
public async Task Delete(int id)
{
@ -162,5 +139,23 @@ namespace MyFirstBlazor.Services
// Save the data
await _localStorage.SetItemAsync("data", currentData);
}
public Task<List<CraftingRecipe>> GetRecipes()
{
var items = new List<CraftingRecipe>
{
new CraftingRecipe
{
Give = new Item { DisplayName = "Diamond", Name = "diamond" },
Have = new List<List<string>>
{
new List<string> { "dirt", "dirt", "dirt" },
new List<string> { "dirt", null, "dirt" },
new List<string> { "dirt", "dirt", "dirt" }
}
}
};
return Task.FromResult(items);
}
}
}

@ -1,4 +1,5 @@
using MyFirstBlazor.Models;
using MyFirstBlazor.Components;
using MyFirstBlazor.Models;
namespace MyFirstBlazor.Services
{
@ -13,5 +14,6 @@ namespace MyFirstBlazor.Services
Task Update(int id, ItemModel model);
Task Delete(int id);
Task<List<CraftingRecipe>> GetRecipes();
}
}

Loading…
Cancel
Save