@ -0,0 +1,6 @@
|
||||
@typeparam TItem
|
||||
<div class="card text-center">
|
||||
@CardHeader(Item)
|
||||
@CardBody(Item)
|
||||
@CardFooter
|
||||
</div>
|
@ -0,0 +1,53 @@
|
||||
<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)
|
||||
{
|
||||
<CascadingValue Value="@this">
|
||||
<CraftingItem Item="item" NoDrop="true"/>
|
||||
</CascadingValue>
|
||||
}
|
||||
</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,14 @@
|
||||
<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,14 @@
|
||||
@code {
|
||||
[Parameter]
|
||||
public RenderFragment ChildContent { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public MyRootComponent RootComponent { get; set; }
|
||||
}
|
||||
|
||||
<div style="border: 1px solid black; padding: 10px;">
|
||||
<strong>MyFirstChildComponent - @RootComponent.Text</strong>
|
||||
<div>
|
||||
@ChildContent
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,16 @@
|
||||
@code {
|
||||
[Parameter]
|
||||
public RenderFragment ChildContent { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public string Text { get; set; }
|
||||
}
|
||||
|
||||
<div style="border: 1px solid black; padding: 10px;">
|
||||
<strong>MyRootComponent - @Text</strong>
|
||||
<div>
|
||||
<CascadingValue Value="@this">
|
||||
@ChildContent
|
||||
</CascadingValue>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,14 @@
|
||||
@code {
|
||||
[Parameter]
|
||||
public RenderFragment ChildContent { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public MyRootComponent RootComponent { get; set; }
|
||||
}
|
||||
|
||||
<div style="border: 1px solid black; padding: 10px;">
|
||||
<strong>MySecondChildComponent - @RootComponent.Text</strong>
|
||||
<div>
|
||||
@ChildContent
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,11 @@
|
||||
@typeparam TItem
|
||||
|
||||
<div>
|
||||
@if ((Items?.Count ?? 0) != 0)
|
||||
{
|
||||
@foreach (var item in Items)
|
||||
{
|
||||
@ShowTemplate(item);
|
||||
}
|
||||
}
|
||||
</div>
|
@ -0,0 +1,8 @@
|
||||
<h3>TestRenderFragment</h3>
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public RenderFragment ChildContent { get; set; }
|
||||
}
|
||||
|
||||
@ChildContent
|
@ -0,0 +1,10 @@
|
||||
<div class="simple-form">
|
||||
|
||||
<p>
|
||||
Are you sure you want to delete @item.DisplayName ?
|
||||
</p>
|
||||
|
||||
<button @onclick="ConfirmDelete" class="btn btn-primary">Delete</button>
|
||||
|
||||
<button @onclick="Cancel" class="btn btn-secondary">Cancel</button>
|
||||
</div>
|
@ -0,0 +1,69 @@
|
||||
@page "/add"
|
||||
|
||||
<h3>Add</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 item in enchantCategories)
|
||||
{
|
||||
<label>
|
||||
<input type="checkbox" @onchange="@(e => OnEnchantCategoriesChange(item, e.Value))" />@item
|
||||
</label>
|
||||
}
|
||||
</div>
|
||||
</p>
|
||||
<p>
|
||||
Repair with:
|
||||
<div>
|
||||
@foreach (var item in repairWith)
|
||||
{
|
||||
<label>
|
||||
<input type="checkbox" @onchange="@(e => OnRepairWithChange(item, e.Value))" />@item
|
||||
</label>
|
||||
}
|
||||
</div>
|
||||
</p>
|
||||
<p>
|
||||
<label>
|
||||
Item image:
|
||||
<InputFile OnChange="@LoadImage" accept=".png" />
|
||||
</label>
|
||||
</p>
|
||||
<p>
|
||||
<label>
|
||||
Accept Condition:
|
||||
<InputCheckbox @bind-Value="itemModel.AcceptCondition" />
|
||||
</label>
|
||||
</p>
|
||||
|
||||
<button type="submit">Submit</button>
|
||||
</EditForm>
|
@ -0,0 +1,35 @@
|
||||
@page "/call-js-example-1"
|
||||
@inject IJSRuntime JS
|
||||
|
||||
<h1>Call JS <code>convertArray</code> Function</h1>
|
||||
|
||||
<p>
|
||||
<button @onclick="ConvertArray">Convert Array</button>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
@text
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<a href="https://www.imdb.com/title/tt0379786/" target="_blank">Serenity</a><br>
|
||||
<a href="https://www.imdb.com/name/nm0472710/" target="_blank">David Krumholtz on IMDB</a>
|
||||
</p>
|
||||
|
||||
@code {
|
||||
private MarkupString text;
|
||||
|
||||
private uint[] quoteArray =
|
||||
new uint[]
|
||||
{
|
||||
60, 101, 109, 62, 67, 97, 110, 39, 116, 32, 115, 116, 111, 112, 32,
|
||||
116, 104, 101, 32, 115, 105, 103, 110, 97, 108, 44, 32, 77, 97,
|
||||
108, 46, 60, 47, 101, 109, 62, 32, 45, 32, 77, 114, 46, 32, 85, 110,
|
||||
105, 118, 101, 114, 115, 101, 10, 10,
|
||||
};
|
||||
|
||||
private async Task ConvertArray()
|
||||
{
|
||||
text = new(await JS.InvokeAsync<string>("convertArray", quoteArray));
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
@page "/call-js-example-3"
|
||||
@inject IJSRuntime JS
|
||||
|
||||
<h1>Call JS Example 3</h1>
|
||||
|
||||
<p>
|
||||
<button @onclick="SetStock">Set Stock</button>
|
||||
</p>
|
||||
|
||||
@if (stockSymbol is not null)
|
||||
{
|
||||
<p>@stockSymbol price: @price.ToString("c")</p>
|
||||
}
|
||||
|
||||
@if (result is not null)
|
||||
{
|
||||
<p>@result</p>
|
||||
}
|
||||
|
||||
@code {
|
||||
private Random r = new();
|
||||
private string? stockSymbol;
|
||||
private decimal price;
|
||||
private string? result;
|
||||
|
||||
private async Task SetStock()
|
||||
{
|
||||
stockSymbol =
|
||||
$"{(char)('A' + r.Next(0, 26))}{(char)('A' + r.Next(0, 26))}";
|
||||
price = r.Next(1, 101);
|
||||
var interopResult =
|
||||
await JS.InvokeAsync<string>("displayTickerAlert2", stockSymbol, price);
|
||||
result = $"Result of TickerChanged call for {stockSymbol} at " +
|
||||
$"{price.ToString("c")}: {interopResult}";
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
@page "/config"
|
||||
<h3>Config</h3>
|
||||
|
||||
<div>
|
||||
<div>MyKey: @Configuration["MyKey"]</div>
|
||||
<div>Position:Title: @Configuration["Position:Title"]</div>
|
||||
<div>Position:Name: @Configuration["Position:Name"]</div>
|
||||
<div>Logging:LogLevel:Default: @Configuration["Logging:LogLevel:Default"]</div>
|
||||
</div>
|
@ -0,0 +1,75 @@
|
||||
@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 item in enchantCategories)
|
||||
{
|
||||
<label>
|
||||
<input type="checkbox" @onchange="@(e => OnEnchantCategoriesChange(item, e.Value))" checked="@(itemModel.EnchantCategories.Contains(item) ? "checked" : null)" />@item
|
||||
</label>
|
||||
}
|
||||
</div>
|
||||
</p>
|
||||
<p>
|
||||
Repair with:
|
||||
<div>
|
||||
@foreach (var item in repairWith)
|
||||
{
|
||||
<label>
|
||||
<input type="checkbox" @onchange="@(e => OnRepairWithChange(item, e.Value))" checked="@(itemModel.RepairWith.Contains(item) ? "checked" : null)" />@item
|
||||
</label>
|
||||
}
|
||||
</div>
|
||||
</p>
|
||||
<p>
|
||||
<label>
|
||||
Current Item image:
|
||||
<img src="data:image/png;base64, @(itemModel.ImageBase64)" class="img-thumbnail" title="@itemModel.DisplayName" alt="@itemModel.DisplayName" style="min-width: 50px; max-width: 150px" />
|
||||
</label>
|
||||
</p>
|
||||
<p>
|
||||
<label>
|
||||
Item image:
|
||||
<InputFile OnChange="@LoadImage" accept=".png" />
|
||||
</label>
|
||||
</p>
|
||||
<p>
|
||||
<label>
|
||||
Accept Condition:
|
||||
<InputCheckbox @bind-Value="itemModel.AcceptCondition" />
|
||||
</label>
|
||||
</p>
|
||||
|
||||
<button type="submit">Submit</button>
|
||||
</EditForm>
|
@ -0,0 +1,22 @@
|
||||
@page "/episodes"
|
||||
@layout DoctorWhoLayout
|
||||
|
||||
<h2>Episodes</h2>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<a href="https://www.bbc.co.uk/programmes/p00vfknq">
|
||||
<em>The Ribos Operation</em>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://www.bbc.co.uk/programmes/p00vfdsb">
|
||||
<em>The Sun Makers</em>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://www.bbc.co.uk/programmes/p00vhc26">
|
||||
<em>Nightmare of Eden</em>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
@ -0,0 +1,36 @@
|
||||
@page "/event-handler-example-1"
|
||||
|
||||
<h1>@currentHeading</h1>
|
||||
|
||||
<p>
|
||||
<button>
|
||||
<label>
|
||||
New title
|
||||
<input @bind="newHeading" />
|
||||
</label>
|
||||
Update heading
|
||||
</button>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<label>
|
||||
<input type="checkbox" @onchange="CheckChanged" />
|
||||
@checkedMessage
|
||||
</label>
|
||||
</p>
|
||||
|
||||
@code {
|
||||
private string currentHeading = "Initial heading";
|
||||
private string? newHeading;
|
||||
private string checkedMessage = "Not changed yet";
|
||||
|
||||
private void UpdateHeading()
|
||||
{
|
||||
currentHeading = $"{newHeading}!!!";
|
||||
}
|
||||
|
||||
private void CheckChanged()
|
||||
{
|
||||
checkedMessage = $"Last changed at {DateTime.Now}";
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
@page "/event-handler-example-2"
|
||||
|
||||
<h1>@currentHeading</h1>
|
||||
|
||||
<p>
|
||||
<label>
|
||||
New title
|
||||
<input @bind="newHeading" />
|
||||
</label>
|
||||
<button @onclick="UpdateHeading">
|
||||
Update heading
|
||||
</button>
|
||||
</p>
|
||||
|
||||
@code {
|
||||
private string currentHeading = "Initial heading";
|
||||
private string? newHeading;
|
||||
|
||||
private async Task UpdateHeading()
|
||||
{
|
||||
await Task.Delay(2000);
|
||||
|
||||
currentHeading = $"{newHeading}!!!";
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
@page "/event-handler-example-3"
|
||||
|
||||
@for (var i = 0; i < 4; i++)
|
||||
{
|
||||
<p>
|
||||
<button @onclick="ReportPointerLocation">
|
||||
Where's my mouse pointer for this button?
|
||||
</button>
|
||||
</p>
|
||||
}
|
||||
|
||||
<p>@mousePointerMessage</p>
|
||||
|
||||
@code {
|
||||
private string? mousePointerMessage;
|
||||
|
||||
private void ReportPointerLocation(MouseEventArgs e)
|
||||
{
|
||||
mousePointerMessage = $"Mouse coordinates: {e.ScreenX}:{e.ScreenY}";
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
@page "/example-tab-set"
|
||||
|
||||
<TabSet>
|
||||
<Tab Title="First tab">
|
||||
<h4>Greetings from the first tab!</h4>
|
||||
|
||||
<label>
|
||||
<input type="checkbox" @bind="showThirdTab" />
|
||||
Toggle third tab
|
||||
</label>
|
||||
</Tab>
|
||||
|
||||
<Tab Title="Second tab">
|
||||
<h4>Hello from the second tab!</h4>
|
||||
</Tab>
|
||||
|
||||
@if (showThirdTab)
|
||||
{
|
||||
<Tab Title="Third tab">
|
||||
<h4>Welcome to the disappearing third tab!</h4>
|
||||
<p>Toggle this tab from the first tab.</p>
|
||||
</Tab>
|
||||
}
|
||||
</TabSet>
|
||||
|
||||
@code {
|
||||
private bool showThirdTab;
|
||||
}
|
@ -1,9 +1,12 @@
|
||||
@page "/"
|
||||
|
||||
@using System.Globalization
|
||||
@using BlazorAppClean.Components
|
||||
<PageTitle>Index</PageTitle>
|
||||
|
||||
<p>
|
||||
<b>CurrentCulture</b>: @CultureInfo.CurrentCulture
|
||||
</p>
|
||||
<h1>Hello, world!</h1>
|
||||
|
||||
Welcome to your new app.
|
||||
|
||||
<SurveyPrompt Title="How is Blazor working for you?" />
|
||||
|
||||
<Crafting Items="Items" Recipes="Recipes" />
|
@ -0,0 +1,51 @@
|
||||
@page "/list"
|
||||
@using BlazorAppClean.Models;
|
||||
|
||||
<h3>@Localizer["Title"]</h3>
|
||||
<div>
|
||||
<NavLink class="btn btn-primary" href="Add" Match="NavLinkMatch.All">
|
||||
<i class="fa fa-plus"></i> Ajouter
|
||||
</NavLink>
|
||||
</div>
|
||||
|
||||
<DataGrid TItem="Item"
|
||||
Data="@items"
|
||||
ReadData="@OnReadData"
|
||||
TotalItems="@totalItem"
|
||||
PageSize="10"
|
||||
ShowPager
|
||||
Responsive>
|
||||
<DataGridColumn TItem="Item" Field="@nameof(Item.Id)" Caption="#" />
|
||||
<DataGridColumn TItem="Item" Field="@nameof(Item.Id)" Caption="Image">
|
||||
<DisplayTemplate>
|
||||
@if (!string.IsNullOrWhiteSpace(context.ImageBase64))
|
||||
{
|
||||
<img src="data:image/png;base64, @(context.ImageBase64)" class="img-thumbnail" title="@context.DisplayName" alt="@context.DisplayName" style="min-width: 50px; max-width: 150px" />
|
||||
}
|
||||
else
|
||||
{
|
||||
<img src="images/default.png" class="img-thumbnail" title="@context.DisplayName" alt="@context.DisplayName" style="max-width: 150px" />
|
||||
}
|
||||
</DisplayTemplate>
|
||||
</DataGridColumn>
|
||||
<DataGridColumn TItem="Item" Field="@nameof(Item.DisplayName)" Caption="Display name" />
|
||||
<DataGridColumn TItem="Item" Field="@nameof(Item.StackSize)" Caption="Stack size" />
|
||||
<DataGridColumn TItem="Item" Field="@nameof(Item.MaxDurability)" Caption="Maximum durability" />
|
||||
<DataGridColumn TItem="Item" Field="@nameof(Item.EnchantCategories)" Caption="Enchant categories">
|
||||
<DisplayTemplate>
|
||||
@(string.Join(", ", ((Item)context).EnchantCategories))
|
||||
</DisplayTemplate>
|
||||
</DataGridColumn>
|
||||
<DataGridColumn TItem="Item" Field="@nameof(Item.RepairWith)" Caption="Repair with">
|
||||
<DisplayTemplate>
|
||||
@(string.Join(", ", ((Item)context).RepairWith))
|
||||
</DisplayTemplate>
|
||||
</DataGridColumn>
|
||||
<DataGridColumn TItem="Item" Field="@nameof(Item.CreatedDate)" Caption="Created date" 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"></i> Editer</a>
|
||||
<button type="button" class="btn btn-primary" @onclick="() => OnDelete(context.Id)"><i class="fa fa-trash"></i> Supprimer</button>
|
||||
</DisplayTemplate>
|
||||
</DataGridColumn>
|
||||
</DataGrid>
|
@ -0,0 +1,29 @@
|
||||
@page "/pets1"
|
||||
|
||||
<h1>Pets</h1>
|
||||
|
||||
<TableTemplate Items="pets" Context="pet">
|
||||
<TableHeader>
|
||||
<th>ID</th>
|
||||
<th>Name</th>
|
||||
</TableHeader>
|
||||
<RowTemplate>
|
||||
<td>@pet.PetId</td>
|
||||
<td>@pet.Name</td>
|
||||
</RowTemplate>
|
||||
</TableTemplate>
|
||||
|
||||
@code {
|
||||
private List<Pet> pets = new()
|
||||
{
|
||||
new Pet { PetId = 2, Name = "Mr. Bigglesworth" },
|
||||
new Pet { PetId = 4, Name = "Salem Saberhagen" },
|
||||
new Pet { PetId = 7, Name = "K-9" }
|
||||
};
|
||||
|
||||
private class Pet
|
||||
{
|
||||
public int PetId { get; set; }
|
||||
public string? Name { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
@page "/pets2"
|
||||
|
||||
<h1>Pets</h1>
|
||||
|
||||
<TableTemplate Items="pets">
|
||||
<TableHeader>
|
||||
<th>ID</th>
|
||||
<th>Name</th>
|
||||
</TableHeader>
|
||||
<RowTemplate Context="pet">
|
||||
<td>@pet.PetId</td>
|
||||
<td>@pet.Name</td>
|
||||
</RowTemplate>
|
||||
</TableTemplate>
|
||||
|
||||
@code {
|
||||
private List<Pet> pets = new()
|
||||
{
|
||||
new Pet { PetId = 2, Name = "Mr. Bigglesworth" },
|
||||
new Pet { PetId = 4, Name = "Salem Saberhagen" },
|
||||
new Pet { PetId = 7, Name = "K-9" }
|
||||
};
|
||||
|
||||
private class Pet
|
||||
{
|
||||
public int PetId { get; set; }
|
||||
public string? Name { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
@page "/pets3"
|
||||
|
||||
<h1>Pets</h1>
|
||||
|
||||
<TableTemplate Items="pets">
|
||||
<TableHeader>
|
||||
<th>ID</th>
|
||||
<th>Name</th>
|
||||
</TableHeader>
|
||||
<RowTemplate>
|
||||
<td>@context.PetId</td>
|
||||
<td>@context.Name</td>
|
||||
</RowTemplate>
|
||||
</TableTemplate>
|
||||
|
||||
@code {
|
||||
private List<Pet> pets = new()
|
||||
{
|
||||
new Pet { PetId = 2, Name = "Mr. Bigglesworth" },
|
||||
new Pet { PetId = 4, Name = "Salem Saberhagen" },
|
||||
new Pet { PetId = 7, Name = "K-9" }
|
||||
};
|
||||
|
||||
private class Pet
|
||||
{
|
||||
public int PetId { get; set; }
|
||||
public string? Name { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
@page "/pets4"
|
||||
|
||||
<h1>Pets</h1>
|
||||
|
||||
<TableTemplate Items="pets" TItem="Pet">
|
||||
<TableHeader>
|
||||
<th>ID</th>
|
||||
<th>Name</th>
|
||||
</TableHeader>
|
||||
<RowTemplate>
|
||||
<td>@context.PetId</td>
|
||||
<td>@context.Name</td>
|
||||
</RowTemplate>
|
||||
</TableTemplate>
|
||||
|
||||
@code {
|
||||
private List<Pet> pets = new()
|
||||
{
|
||||
new Pet { PetId = 2, Name = "Mr. Bigglesworth" },
|
||||
new Pet { PetId = 4, Name = "Salem Saberhagen" },
|
||||
new Pet { PetId = 7, Name = "K-9" }
|
||||
};
|
||||
|
||||
private class Pet
|
||||
{
|
||||
public int PetId { get; set; }
|
||||
public string? Name { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
@page "/themed-counter"
|
||||
@using BlazorSample.UIThemeClasses
|
||||
|
||||
<h1>Themed Counter</h1>
|
||||
|
||||
<p>Current count: @currentCount</p>
|
||||
|
||||
<p>
|
||||
<button class="btn" @onclick="IncrementCount">
|
||||
Increment Counter (Unthemed)
|
||||
</button>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<button
|
||||
class="btn @(ThemeInfo is not null ? ThemeInfo.ButtonClass : string.Empty)"
|
||||
@onclick="IncrementCount">
|
||||
Increment Counter (Themed)
|
||||
</button>
|
||||
</p>
|
||||
|
||||
@code {
|
||||
private int currentCount = 0;
|
||||
|
||||
[CascadingParameter]
|
||||
protected ThemeInfo? ThemeInfo { get; set; }
|
||||
|
||||
private void IncrementCount()
|
||||
{
|
||||
currentCount++;
|
||||
}
|
||||
}
|
@ -0,0 +1,123 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="Title" xml:space="preserve">
|
||||
<value>List of elements</value>
|
||||
</data>
|
||||
</root>
|
@ -0,0 +1,123 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="Title" xml:space="preserve">
|
||||
<value>Liste des éléments</value>
|
||||
</data>
|
||||
</root>
|
@ -0,0 +1,123 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="Title" xml:space="preserve">
|
||||
<value>Items List</value>
|
||||
</data>
|
||||
</root>
|
@ -0,0 +1,43 @@
|
||||
@using System.Globalization
|
||||
@inject NavigationManager NavigationManager
|
||||
|
||||
<p>
|
||||
<label>
|
||||
Select your locale:
|
||||
<select @bind="Culture">
|
||||
@foreach (var culture in supportedCultures)
|
||||
{
|
||||
<option value="@culture">@culture.DisplayName</option>
|
||||
}
|
||||
</select>
|
||||
</label>
|
||||
</p>
|
||||
|
||||
@code
|
||||
{
|
||||
private CultureInfo[] supportedCultures = new[]
|
||||
{
|
||||
new CultureInfo("en-US"),
|
||||
new CultureInfo("fr-FR")
|
||||
};
|
||||
|
||||
private CultureInfo Culture
|
||||
{
|
||||
get => CultureInfo.CurrentCulture;
|
||||
set
|
||||
{
|
||||
if (CultureInfo.CurrentUICulture == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var culture = value.Name.ToLower(CultureInfo.InvariantCulture);
|
||||
|
||||
var uri = new Uri(this.NavigationManager.Uri).GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
|
||||
var query = $"?culture={Uri.EscapeDataString(culture)}&" + $"redirectUri={Uri.EscapeDataString(uri)}";
|
||||
|
||||
// Redirect the user to the culture controller to set the cookie
|
||||
this.NavigationManager.NavigateTo("/Culture/SetCulture" + query, forceLoad: true);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
@inherits LayoutComponentBase
|
||||
|
||||
<header>
|
||||
<h1>Doctor Who™ Episode Database</h1>
|
||||
</header>
|
||||
|
||||
<nav>
|
||||
<a href="masterlist">Master Episode List</a>
|
||||
<a href="search">Search</a>
|
||||
<a href="new">Add Episode</a>
|
||||
</nav>
|
||||
|
||||
@Body
|
||||
|
||||
<footer>
|
||||
@TrademarkMessage
|
||||
</footer>
|
||||
|
||||
@code {
|
||||
public string TrademarkMessage { get; set; } =
|
||||
"Doctor Who is a registered trademark of the BBC. " +
|
||||
"https://www.doctorwho.tv/";
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
@using BlazorSample.UIInterfaces
|
||||
@implements ITab
|
||||
|
||||
<li>
|
||||
<a @onclick="ActivateTab" class="nav-link @TitleCssClass" role="button">
|
||||
@Title
|
||||
</a>
|
||||
</li>
|
||||
|
||||
@code {
|
||||
[CascadingParameter]
|
||||
public TabSet ContainerTabSet { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public string Title { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public RenderFragment ChildContent { get; set; }
|
||||
|
||||
private string TitleCssClass =>
|
||||
ContainerTabSet.ActiveTab == this ? "active" : null;
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
ContainerTabSet.AddTab(this);
|
||||
}
|
||||
|
||||
private void ActivateTab()
|
||||
{
|
||||
ContainerTabSet.SetActiveTab(this);
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
@using BlazorSample.UIInterfaces
|
||||
|
||||
<!-- Display the tab headers -->
|
||||
|
||||
<CascadingValue Value=this>
|
||||
<ul class="nav nav-tabs">
|
||||
@ChildContent
|
||||
</ul>
|
||||
</CascadingValue>
|
||||
|
||||
<!-- Display body for only the active tab -->
|
||||
|
||||
<div class="nav-tabs-body p-4">
|
||||
@ActiveTab?.ChildContent
|
||||
</div>
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public RenderFragment ChildContent { get; set; }
|
||||
|
||||
public ITab ActiveTab { get; private set; }
|
||||
|
||||
public void AddTab(ITab tab)
|
||||
{
|
||||
if (ActiveTab == null)
|
||||
{
|
||||
SetActiveTab(tab);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetActiveTab(ITab tab)
|
||||
{
|
||||
if (ActiveTab != tab)
|
||||
{
|
||||
ActiveTab = tab;
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
@typeparam TItem
|
||||
@using System.Diagnostics.CodeAnalysis
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>@TableHeader</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var item in Items)
|
||||
{
|
||||
if (RowTemplate is not null)
|
||||
{
|
||||
<tr>@RowTemplate(item)</tr>
|
||||
}
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public RenderFragment? TableHeader { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public RenderFragment<TItem>? RowTemplate { get; set; }
|
||||
|
||||
[Parameter, AllowNull]
|
||||
public IReadOnlyList<TItem> Items { get; set; }
|
||||
}
|
@ -0,0 +1,415 @@
|
||||
[
|
||||
{
|
||||
"id": 1,
|
||||
"displayname": "Polaria",
|
||||
"name": "polaria",
|
||||
"stacksize": 34,
|
||||
"maxdurability": 27,
|
||||
"enchantcategories": [
|
||||
"breakable",
|
||||
"vanishable",
|
||||
"digger"
|
||||
],
|
||||
"repairwith": [
|
||||
"spruce_planks",
|
||||
"crimson_planks"
|
||||
],
|
||||
"createddate": "2018-03-25",
|
||||
"updateddate": null
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"displayname": "Sureplex",
|
||||
"name": "sureplex",
|
||||
"stacksize": 64,
|
||||
"maxdurability": 25,
|
||||
"enchantcategories": [],
|
||||
"repairwith": [],
|
||||
"createddate": "2022-06-25",
|
||||
"updateddate": "2016-11-10"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"displayname": "Magneato",
|
||||
"name": "magneato",
|
||||
"stacksize": 9,
|
||||
"maxdurability": 95,
|
||||
"enchantcategories": [],
|
||||
"repairwith": [
|
||||
"birch_planks",
|
||||
"crimson_planks"
|
||||
],
|
||||
"createddate": "2017-09-11",
|
||||
"updateddate": "2021-11-02"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"displayname": "Lyria",
|
||||
"name": "lyria",
|
||||
"stacksize": 59,
|
||||
"maxdurability": 66,
|
||||
"enchantcategories": [
|
||||
"digger",
|
||||
"armor"
|
||||
],
|
||||
"repairwith": [],
|
||||
"createddate": "2017-07-08",
|
||||
"updateddate": "2019-08-02"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"displayname": "Limage",
|
||||
"name": "limage",
|
||||
"stacksize": 63,
|
||||
"maxdurability": 26,
|
||||
"enchantcategories": [
|
||||
"armor_chest",
|
||||
"breakable",
|
||||
"weapon"
|
||||
],
|
||||
"repairwith": [
|
||||
"warped_planks",
|
||||
"spruce_planks"
|
||||
],
|
||||
"createddate": "2014-04-01",
|
||||
"updateddate": null
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"displayname": "Olucore",
|
||||
"name": "olucore",
|
||||
"stacksize": 55,
|
||||
"maxdurability": 34,
|
||||
"enchantcategories": [
|
||||
"vanishable",
|
||||
"armor_chest",
|
||||
"digger"
|
||||
],
|
||||
"repairwith": [
|
||||
"dark_oak_planks",
|
||||
"dark_oak_planks"
|
||||
],
|
||||
"createddate": "2021-06-20",
|
||||
"updateddate": null
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"displayname": "Goko",
|
||||
"name": "goko",
|
||||
"stacksize": 62,
|
||||
"maxdurability": 15,
|
||||
"enchantcategories": [
|
||||
"digger",
|
||||
"breakable",
|
||||
"armor_chest"
|
||||
],
|
||||
"repairwith": [],
|
||||
"createddate": "2017-06-02",
|
||||
"updateddate": "2020-12-29"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"displayname": "Colaire",
|
||||
"name": "colaire",
|
||||
"stacksize": 20,
|
||||
"maxdurability": 103,
|
||||
"enchantcategories": [],
|
||||
"repairwith": [],
|
||||
"createddate": "2021-12-12",
|
||||
"updateddate": "2022-05-30"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"displayname": "Endipine",
|
||||
"name": "endipine",
|
||||
"stacksize": 55,
|
||||
"maxdurability": 48,
|
||||
"enchantcategories": [
|
||||
"digger"
|
||||
],
|
||||
"repairwith": [],
|
||||
"createddate": "2018-11-10",
|
||||
"updateddate": null
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"displayname": "Oceanica",
|
||||
"name": "oceanica",
|
||||
"stacksize": 33,
|
||||
"maxdurability": 76,
|
||||
"enchantcategories": [
|
||||
"armor",
|
||||
"vanishable",
|
||||
"armor_head"
|
||||
],
|
||||
"repairwith": [
|
||||
"dark_oak_planks"
|
||||
],
|
||||
"createddate": "2020-08-26",
|
||||
"updateddate": null
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"displayname": "Opticom",
|
||||
"name": "opticom",
|
||||
"stacksize": 14,
|
||||
"maxdurability": 76,
|
||||
"enchantcategories": [
|
||||
"armor"
|
||||
],
|
||||
"repairwith": [
|
||||
"warped_planks"
|
||||
],
|
||||
"createddate": "2022-05-15",
|
||||
"updateddate": null
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"displayname": "Futuris",
|
||||
"name": "futuris",
|
||||
"stacksize": 29,
|
||||
"maxdurability": 19,
|
||||
"enchantcategories": [
|
||||
"armor",
|
||||
"vanishable",
|
||||
"armor"
|
||||
],
|
||||
"repairwith": [
|
||||
"crimson_planks"
|
||||
],
|
||||
"createddate": "2021-07-30",
|
||||
"updateddate": null
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"displayname": "Permadyne",
|
||||
"name": "permadyne",
|
||||
"stacksize": 14,
|
||||
"maxdurability": 54,
|
||||
"enchantcategories": [
|
||||
"digger",
|
||||
"breakable",
|
||||
"breakable"
|
||||
],
|
||||
"repairwith": [],
|
||||
"createddate": "2019-02-08",
|
||||
"updateddate": "2015-03-26"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"displayname": "Ecratic",
|
||||
"name": "ecratic",
|
||||
"stacksize": 62,
|
||||
"maxdurability": 112,
|
||||
"enchantcategories": [],
|
||||
"repairwith": [
|
||||
"warped_planks",
|
||||
"acacia_planks"
|
||||
],
|
||||
"createddate": "2017-06-10",
|
||||
"updateddate": null
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"displayname": "Uni",
|
||||
"name": "uni",
|
||||
"stacksize": 12,
|
||||
"maxdurability": 37,
|
||||
"enchantcategories": [
|
||||
"digger"
|
||||
],
|
||||
"repairwith": [],
|
||||
"createddate": "2017-10-22",
|
||||
"updateddate": null
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"displayname": "Avenetro",
|
||||
"name": "avenetro",
|
||||
"stacksize": 28,
|
||||
"maxdurability": 39,
|
||||
"enchantcategories": [
|
||||
"digger",
|
||||
"armor",
|
||||
"vanishable"
|
||||
],
|
||||
"repairwith": [],
|
||||
"createddate": "2020-11-12",
|
||||
"updateddate": "2017-08-03"
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"displayname": "Zilencio",
|
||||
"name": "zilencio",
|
||||
"stacksize": 25,
|
||||
"maxdurability": 123,
|
||||
"enchantcategories": [
|
||||
"digger"
|
||||
],
|
||||
"repairwith": [],
|
||||
"createddate": "2020-02-21",
|
||||
"updateddate": "2014-07-08"
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"displayname": "Genekom",
|
||||
"name": "genekom",
|
||||
"stacksize": 32,
|
||||
"maxdurability": 117,
|
||||
"enchantcategories": [
|
||||
"vanishable",
|
||||
"vanishable",
|
||||
"digger"
|
||||
],
|
||||
"repairwith": [],
|
||||
"createddate": "2015-06-06",
|
||||
"updateddate": "2021-12-24"
|
||||
},
|
||||
{
|
||||
"id": 19,
|
||||
"displayname": "Intradisk",
|
||||
"name": "intradisk",
|
||||
"stacksize": 14,
|
||||
"maxdurability": 3,
|
||||
"enchantcategories": [
|
||||
"armor_head"
|
||||
],
|
||||
"repairwith": [
|
||||
"crimson_planks"
|
||||
],
|
||||
"createddate": "2016-09-11",
|
||||
"updateddate": "2019-09-11"
|
||||
},
|
||||
{
|
||||
"id": 20,
|
||||
"displayname": "Netropic",
|
||||
"name": "netropic",
|
||||
"stacksize": 27,
|
||||
"maxdurability": 73,
|
||||
"enchantcategories": [
|
||||
"armor",
|
||||
"vanishable"
|
||||
],
|
||||
"repairwith": [
|
||||
"birch_planks",
|
||||
"spruce_planks"
|
||||
],
|
||||
"createddate": "2021-11-26",
|
||||
"updateddate": "2022-12-02"
|
||||
},
|
||||
{
|
||||
"id": 21,
|
||||
"displayname": "Sonique",
|
||||
"name": "sonique",
|
||||
"stacksize": 36,
|
||||
"maxdurability": 13,
|
||||
"enchantcategories": [
|
||||
"weapon",
|
||||
"armor_chest"
|
||||
],
|
||||
"repairwith": [],
|
||||
"createddate": "2019-03-31",
|
||||
"updateddate": null
|
||||
},
|
||||
{
|
||||
"id": 22,
|
||||
"displayname": "Anixang",
|
||||
"name": "anixang",
|
||||
"stacksize": 46,
|
||||
"maxdurability": 84,
|
||||
"enchantcategories": [
|
||||
"weapon",
|
||||
"breakable",
|
||||
"armor"
|
||||
],
|
||||
"repairwith": [],
|
||||
"createddate": "2014-08-12",
|
||||
"updateddate": null
|
||||
},
|
||||
{
|
||||
"id": 23,
|
||||
"displayname": "Applidec",
|
||||
"name": "applidec",
|
||||
"stacksize": 9,
|
||||
"maxdurability": 110,
|
||||
"enchantcategories": [],
|
||||
"repairwith": [],
|
||||
"createddate": "2014-01-04",
|
||||
"updateddate": "2022-02-15"
|
||||
},
|
||||
{
|
||||
"id": 24,
|
||||
"displayname": "Geologix",
|
||||
"name": "geologix",
|
||||
"stacksize": 3,
|
||||
"maxdurability": 26,
|
||||
"enchantcategories": [
|
||||
"breakable",
|
||||
"vanishable"
|
||||
],
|
||||
"repairwith": [
|
||||
"warped_planks"
|
||||
],
|
||||
"createddate": "2020-05-19",
|
||||
"updateddate": "2020-10-31"
|
||||
},
|
||||
{
|
||||
"id": 25,
|
||||
"displayname": "Combogen",
|
||||
"name": "combogen",
|
||||
"stacksize": 29,
|
||||
"maxdurability": 114,
|
||||
"enchantcategories": [
|
||||
"weapon"
|
||||
],
|
||||
"repairwith": [
|
||||
"dark_oak_planks",
|
||||
"acacia_planks"
|
||||
],
|
||||
"createddate": "2021-03-06",
|
||||
"updateddate": null
|
||||
},
|
||||
{
|
||||
"id": 26,
|
||||
"displayname": "Isoswitch",
|
||||
"name": "isoswitch",
|
||||
"stacksize": 32,
|
||||
"maxdurability": 97,
|
||||
"enchantcategories": [
|
||||
"armor_head",
|
||||
"digger",
|
||||
"digger"
|
||||
],
|
||||
"repairwith": [],
|
||||
"createddate": "2015-07-01",
|
||||
"updateddate": null
|
||||
},
|
||||
{
|
||||
"id": 27,
|
||||
"displayname": "Otherside",
|
||||
"name": "otherside",
|
||||
"stacksize": 4,
|
||||
"maxdurability": 8,
|
||||
"enchantcategories": [
|
||||
"weapon"
|
||||
],
|
||||
"repairwith": [
|
||||
"warped_planks"
|
||||
],
|
||||
"createddate": "2020-10-03",
|
||||
"updateddate": null
|
||||
},
|
||||
{
|
||||
"id": 28,
|
||||
"displayname": "Songbird",
|
||||
"name": "songbird",
|
||||
"stacksize": 29,
|
||||
"maxdurability": 123,
|
||||
"enchantcategories": [
|
||||
"armor"
|
||||
],
|
||||
"repairwith": [],
|
||||
"createddate": "2021-01-10",
|
||||
"updateddate": null
|
||||
}
|
||||
]
|
After Width: | Height: | Size: 210 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 348 KiB |
After Width: | Height: | Size: 210 KiB |
@ -0,0 +1,449 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="CraftingController.cs" company="UCA Clermont-Ferrand">
|
||||
// Copyright (c) UCA Clermont-Ferrand All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace Minecraft.Crafting.Api.Controllers
|
||||
{
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Minecraft.Crafting.Api.Models;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
/// <summary>
|
||||
/// The crafting controller.
|
||||
/// </summary>
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class CraftingController : ControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// The json serializer options.
|
||||
/// </summary>
|
||||
private readonly JsonSerializerOptions _jsonSerializerOptions = new()
|
||||
{
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||
WriteIndented = true,
|
||||
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Adds the specified item.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <returns>The async task.</returns>
|
||||
[HttpPost]
|
||||
[Route("")]
|
||||
public Task Add(Item item)
|
||||
{
|
||||
var data = JsonSerializer.Deserialize<List<Item>>(System.IO.File.ReadAllText("Data/items.json"), _jsonSerializerOptions);
|
||||
|
||||
if (data == null)
|
||||
{
|
||||
throw new Exception("Unable to get the items.");
|
||||
}
|
||||
|
||||
data.Add(item);
|
||||
|
||||
System.IO.File.WriteAllText("Data/items.json", JsonSerializer.Serialize(data, _jsonSerializerOptions));
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get all items.
|
||||
/// </summary>
|
||||
/// <returns>All items.</returns>
|
||||
[HttpGet]
|
||||
[Route("all")]
|
||||
public Task<List<Item>> All()
|
||||
{
|
||||
var data = JsonSerializer.Deserialize<List<Item>>(System.IO.File.ReadAllText("Data/items.json"), _jsonSerializerOptions);
|
||||
|
||||
if (data == null)
|
||||
{
|
||||
throw new Exception("Unable to get the items.");
|
||||
}
|
||||
|
||||
return Task.FromResult(data.ToList());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Count the number of items.
|
||||
/// </summary>
|
||||
/// <returns>The number of items.</returns>
|
||||
[HttpGet]
|
||||
[Route("count")]
|
||||
public Task<int> Count()
|
||||
{
|
||||
var data = JsonSerializer.Deserialize<List<Item>>(System.IO.File.ReadAllText("Data/items.json"), _jsonSerializerOptions);
|
||||
|
||||
if (data == null)
|
||||
{
|
||||
throw new Exception("Unable to get the items.");
|
||||
}
|
||||
|
||||
return Task.FromResult(data.Count);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the specified identifier.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier.</param>
|
||||
/// <returns>The async task.</returns>
|
||||
[HttpDelete]
|
||||
[Route("{id}")]
|
||||
public Task Delete(int id)
|
||||
{
|
||||
var data = JsonSerializer.Deserialize<List<Item>>(System.IO.File.ReadAllText("Data/items.json"), _jsonSerializerOptions);
|
||||
|
||||
if (data == null)
|
||||
{
|
||||
throw new Exception("Unable to get the items.");
|
||||
}
|
||||
|
||||
var item = data.FirstOrDefault(w => w.Id == id);
|
||||
|
||||
if (item == null)
|
||||
{
|
||||
throw new Exception($"Unable to found the item with ID: {id}");
|
||||
}
|
||||
|
||||
data.Remove(item);
|
||||
|
||||
System.IO.File.WriteAllText("Data/items.json", JsonSerializer.Serialize(data, _jsonSerializerOptions));
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the item by identifier.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier.</param>
|
||||
/// <returns>The item.</returns>
|
||||
[HttpGet]
|
||||
[Route("{id}")]
|
||||
public Task<Item> GetById(int id)
|
||||
{
|
||||
var data = JsonSerializer.Deserialize<List<Item>>(System.IO.File.ReadAllText("Data/items.json"), _jsonSerializerOptions);
|
||||
|
||||
if (data == null)
|
||||
{
|
||||
throw new Exception("Unable to get the items.");
|
||||
}
|
||||
|
||||
var item = data.FirstOrDefault(w => w.Id == id);
|
||||
|
||||
if (item == null)
|
||||
{
|
||||
throw new Exception($"Unable to found the item with ID: {id}");
|
||||
}
|
||||
|
||||
return Task.FromResult(item);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the item by name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <returns>
|
||||
/// The item.
|
||||
/// </returns>
|
||||
[HttpGet]
|
||||
[Route("by-name/{name}")]
|
||||
public Task<Item> GetByName(string name)
|
||||
{
|
||||
var data = JsonSerializer.Deserialize<List<Item>>(System.IO.File.ReadAllText("Data/items.json"), _jsonSerializerOptions);
|
||||
|
||||
if (data == null)
|
||||
{
|
||||
throw new Exception("Unable to get the items.");
|
||||
}
|
||||
|
||||
var item = data.FirstOrDefault(w => w.Name.ToLowerInvariant() == name.ToLowerInvariant());
|
||||
|
||||
if (item == null)
|
||||
{
|
||||
throw new Exception($"Unable to found the item with name: {name}");
|
||||
}
|
||||
|
||||
return Task.FromResult(item);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the recipes.
|
||||
/// </summary>
|
||||
/// <returns>The recipes.</returns>
|
||||
[HttpGet]
|
||||
[Route("recipe")]
|
||||
public Task<List<Recipe>> GetRecipe()
|
||||
{
|
||||
if (!System.IO.File.Exists("Data/convert-recipes.json"))
|
||||
{
|
||||
ResetRecipes();
|
||||
}
|
||||
|
||||
var data = JsonSerializer.Deserialize<List<Recipe>>(System.IO.File.ReadAllText("Data/convert-recipes.json"), _jsonSerializerOptions);
|
||||
|
||||
if (data == null)
|
||||
{
|
||||
throw new Exception("Unable to get the recipes.");
|
||||
}
|
||||
|
||||
return Task.FromResult(data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the items with pagination.
|
||||
/// </summary>
|
||||
/// <param name="currentPage">The current page.</param>
|
||||
/// <param name="pageSize">Size of the page.</param>
|
||||
/// <returns>The items.</returns>
|
||||
[HttpGet]
|
||||
[Route("")]
|
||||
public Task<List<Item>> List(int currentPage, int pageSize)
|
||||
{
|
||||
var data = JsonSerializer.Deserialize<List<Item>>(System.IO.File.ReadAllText("Data/items.json"), _jsonSerializerOptions);
|
||||
|
||||
if (data == null)
|
||||
{
|
||||
throw new Exception("Unable to get the items.");
|
||||
}
|
||||
|
||||
return Task.FromResult(data.Skip((currentPage - 1) * pageSize).Take(pageSize).ToList());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets the items.
|
||||
/// </summary>
|
||||
/// <returns>The async task.</returns>
|
||||
[HttpGet]
|
||||
[Route("reset-items")]
|
||||
public Task ResetItems()
|
||||
{
|
||||
if (!System.IO.File.Exists("Data/items.json"))
|
||||
{
|
||||
System.IO.File.Delete("Data/items.json");
|
||||
}
|
||||
|
||||
var data = JsonSerializer.Deserialize<List<Item>>(System.IO.File.ReadAllText("Data/items-original.json"), _jsonSerializerOptions);
|
||||
|
||||
if (data == null)
|
||||
{
|
||||
throw new Exception("Unable to get the items.");
|
||||
}
|
||||
|
||||
var defaultImage = Convert.ToBase64String(System.IO.File.ReadAllBytes("Images/default.png"));
|
||||
|
||||
var imageTranslation = new Dictionary<string, string>
|
||||
{
|
||||
{ "stone_slab", "smooth_stone_slab_side" },
|
||||
{ "sticky_piston", "piston_top_sticky" },
|
||||
{ "mob_spawner", "spawner" },
|
||||
{ "chest", "chest_minecart" },
|
||||
{ "stone_stairs", "stairs" },
|
||||
};
|
||||
|
||||
foreach (var item in data)
|
||||
{
|
||||
var imageFilepath = defaultImage;
|
||||
|
||||
if (System.IO.File.Exists($"Images/{item.Name}.png"))
|
||||
{
|
||||
imageFilepath = Convert.ToBase64String(System.IO.File.ReadAllBytes($"Images/{item.Name}.png"));
|
||||
}
|
||||
|
||||
if (imageFilepath == defaultImage && System.IO.File.Exists($"Images/{item.Name}_top.png"))
|
||||
{
|
||||
imageFilepath = Convert.ToBase64String(System.IO.File.ReadAllBytes($"Images/{item.Name}_top.png"));
|
||||
}
|
||||
|
||||
if (imageFilepath == defaultImage && System.IO.File.Exists($"Images/{item.Name}_front.png"))
|
||||
{
|
||||
imageFilepath = Convert.ToBase64String(System.IO.File.ReadAllBytes($"Images/{item.Name}_front.png"));
|
||||
}
|
||||
|
||||
if (imageFilepath == defaultImage && System.IO.File.Exists($"Images/white_{item.Name}.png"))
|
||||
{
|
||||
imageFilepath = Convert.ToBase64String(System.IO.File.ReadAllBytes($"Images/white_{item.Name}.png"));
|
||||
}
|
||||
|
||||
if (imageFilepath == defaultImage && System.IO.File.Exists($"Images/oak_{item.Name}.png"))
|
||||
{
|
||||
imageFilepath = Convert.ToBase64String(System.IO.File.ReadAllBytes($"Images/oak_{item.Name}.png"));
|
||||
}
|
||||
|
||||
if (imageFilepath == defaultImage && System.IO.File.Exists($"Images/{item.DisplayName.ToLower().Replace(" ", "_")}.png"))
|
||||
{
|
||||
imageFilepath = Convert.ToBase64String(System.IO.File.ReadAllBytes($"Images/{item.DisplayName.ToLower().Replace(" ", "_")}.png"));
|
||||
}
|
||||
|
||||
if (imageFilepath == defaultImage && imageTranslation.ContainsKey(item.Name))
|
||||
{
|
||||
imageFilepath = Convert.ToBase64String(System.IO.File.ReadAllBytes($"Images/{imageTranslation[item.Name]}.png"));
|
||||
}
|
||||
|
||||
item.ImageBase64 = imageFilepath;
|
||||
}
|
||||
|
||||
System.IO.File.WriteAllText("Data/items.json", JsonSerializer.Serialize(data, _jsonSerializerOptions));
|
||||
|
||||
return Task.FromResult(data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets the recipes.
|
||||
/// </summary>
|
||||
/// <returns>The async task.</returns>
|
||||
[HttpGet]
|
||||
[Route("reset-recipes")]
|
||||
public Task ResetRecipes()
|
||||
{
|
||||
if (!System.IO.File.Exists("Data/convert-recipes.json"))
|
||||
{
|
||||
System.IO.File.Delete("Data/convert-recipes.json");
|
||||
}
|
||||
|
||||
ConvertRecipes();
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the specified identifier.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier.</param>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <returns>The async task.</returns>
|
||||
[HttpPut]
|
||||
[Route("{id}")]
|
||||
public Task Update(int id, Item item)
|
||||
{
|
||||
var data = JsonSerializer.Deserialize<List<Item>>(System.IO.File.ReadAllText("Data/items.json"), _jsonSerializerOptions);
|
||||
|
||||
var itemOriginal = data?.FirstOrDefault(w => w.Id == id);
|
||||
|
||||
if (itemOriginal == null)
|
||||
{
|
||||
throw new Exception($"Unable to found the item with ID: {id}");
|
||||
}
|
||||
|
||||
itemOriginal.Id = item.Id;
|
||||
itemOriginal.Name = item.Name;
|
||||
itemOriginal.CreatedDate = item.CreatedDate;
|
||||
itemOriginal.DisplayName = item.DisplayName;
|
||||
itemOriginal.EnchantCategories = item.EnchantCategories;
|
||||
itemOriginal.MaxDurability = item.MaxDurability;
|
||||
itemOriginal.RepairWith = item.RepairWith;
|
||||
itemOriginal.StackSize = item.StackSize;
|
||||
itemOriginal.UpdatedDate = item.UpdatedDate;
|
||||
|
||||
System.IO.File.WriteAllText("Data/items.json", JsonSerializer.Serialize(data, _jsonSerializerOptions));
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the item.
|
||||
/// </summary>
|
||||
/// <param name="items">The items.</param>
|
||||
/// <param name="inShape">The in shape.</param>
|
||||
/// <param name="line">The line.</param>
|
||||
/// <param name="row">The row.</param>
|
||||
/// <returns>The name of the item.</returns>
|
||||
private static string GetItemName(List<Item> items, InShape[][] inShape, int line, int row)
|
||||
{
|
||||
if (inShape.Length < line + 1)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (inShape[line].Length < row + 1)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var id = inShape[line][row].Integer ?? inShape[line][row].IngredientClass?.Id;
|
||||
|
||||
if (id == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return GetItemName(items, id.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the item.
|
||||
/// </summary>
|
||||
/// <param name="items">The items.</param>
|
||||
/// <param name="id">The identifier.</param>
|
||||
/// <returns>The name of the item.</returns>
|
||||
private static string GetItemName(List<Item> items, long id)
|
||||
{
|
||||
var item = items.FirstOrDefault(w => w.Id == id);
|
||||
return item?.Name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the recipes.
|
||||
/// </summary>
|
||||
private void ConvertRecipes()
|
||||
{
|
||||
var data = JsonSerializer.Deserialize<List<Item>>(System.IO.File.ReadAllText("Data/items.json"), _jsonSerializerOptions);
|
||||
|
||||
if (data == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var recipes = Recipes.FromJson(System.IO.File.ReadAllText("Data/recipes.json"));
|
||||
|
||||
var items = new List<Recipe>();
|
||||
|
||||
foreach (var recipe in recipes.SelectMany(s => s.Value))
|
||||
{
|
||||
if (recipe.InShape == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var giveItem = data.FirstOrDefault(w => w.Id == recipe.Result.Id);
|
||||
|
||||
if (giveItem == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
items.Add(new Recipe
|
||||
{
|
||||
Give = giveItem,
|
||||
Have = new List<List<string>>
|
||||
{
|
||||
new()
|
||||
{
|
||||
GetItemName(data, recipe.InShape, 0, 0),
|
||||
GetItemName(data, recipe.InShape, 0, 1),
|
||||
GetItemName(data, recipe.InShape, 0, 2)
|
||||
},
|
||||
new()
|
||||
{
|
||||
GetItemName(data, recipe.InShape, 1, 0),
|
||||
GetItemName(data, recipe.InShape, 1, 1),
|
||||
GetItemName(data, recipe.InShape, 1, 2)
|
||||
},
|
||||
new()
|
||||
{
|
||||
GetItemName(data, recipe.InShape, 2, 0),
|
||||
GetItemName(data, recipe.InShape, 2, 1),
|
||||
GetItemName(data, recipe.InShape, 2, 2)
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
System.IO.File.WriteAllText("Data/convert-recipes.json", JsonSerializer.Serialize(items, _jsonSerializerOptions));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
|
||||
WORKDIR /app
|
||||
EXPOSE 80
|
||||
EXPOSE 443
|
||||
|
||||
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
|
||||
WORKDIR /src
|
||||
COPY ["src/Minecraft.Crafting.Api/Minecraft.Crafting.Api.csproj", "Minecraft.Crafting.Api/"]
|
||||
RUN dotnet restore "Minecraft.Crafting.Api/Minecraft.Crafting.Api.csproj"
|
||||
COPY src/. .
|
||||
WORKDIR "/src/Minecraft.Crafting.Api"
|
||||
RUN dotnet build "Minecraft.Crafting.Api.csproj" -c Release -o /app/build
|
||||
|
||||
FROM build AS publish
|
||||
RUN dotnet publish "Minecraft.Crafting.Api.csproj" -c Release -o /app/publish /p:UseAppHost=false
|
||||
|
||||
FROM base AS final
|
||||
WORKDIR /app
|
||||
COPY --from=publish /app/publish .
|
||||
ENTRYPOINT ["dotnet", "Minecraft.Crafting.Api.dll"]
|
After Width: | Height: | Size: 343 B |
After Width: | Height: | Size: 376 B |
After Width: | Height: | Size: 135 B |
After Width: | Height: | Size: 252 B |
After Width: | Height: | Size: 264 B |
After Width: | Height: | Size: 249 B |
After Width: | Height: | Size: 259 B |
After Width: | Height: | Size: 301 B |
After Width: | Height: | Size: 269 B |
After Width: | Height: | Size: 232 B |
After Width: | Height: | Size: 206 B |
After Width: | Height: | Size: 172 B |
After Width: | Height: | Size: 294 B |
After Width: | Height: | Size: 295 B |
After Width: | Height: | Size: 250 B |
After Width: | Height: | Size: 284 B |
After Width: | Height: | Size: 249 B |
After Width: | Height: | Size: 199 B |