From e5aad8637096f483ecea8c9069e990f7232500e2 Mon Sep 17 00:00:00 2001 From: Alexis DRAI Date: Mon, 20 Feb 2023 22:31:34 +0100 Subject: [PATCH] :fire: :necktie: Clean up, add components :bookmark: pick it back up here : https://codefirst.iut.uca.fr/documentation/julien.riboulet/docusaurus/Blazor/api/introduction/ --- blazor_lab/Components/Crafting.razor | 50 +++++++ blazor_lab/Components/Crafting.razor.cs | 80 ++++++++++++ blazor_lab/Components/Crafting.razor.css | 19 +++ blazor_lab/Components/Crafting.razor.js | 16 +++ blazor_lab/Components/CraftingAction.cs | 11 ++ blazor_lab/Components/CraftingItem.razor | 13 ++ blazor_lab/Components/CraftingItem.razor.cs | 63 +++++++++ blazor_lab/Components/CraftingItem.razor.css | 6 + blazor_lab/Components/CraftingRecipe.cs | 10 ++ blazor_lab/Data/WeatherForecast.cs | 13 -- blazor_lab/Data/WeatherForecastService.cs | 20 --- blazor_lab/Modals/DeleteConfirmation.razor.cs | 2 +- blazor_lab/Models/Cake.cs | 9 ++ blazor_lab/Pages/Add.razor.cs | 2 +- blazor_lab/Pages/Admin/Index.razor | 3 - blazor_lab/Pages/Admin/Users.razor | 2 - blazor_lab/Pages/Admin/_Imports.razor | 1 - blazor_lab/Pages/Counter.razor | 18 --- blazor_lab/Pages/FetchData.razor | 48 ------- blazor_lab/Pages/Index.razor | 11 +- blazor_lab/Pages/Index.razor.cs | 32 +++++ blazor_lab/Pages/List.razor | 2 +- blazor_lab/Pages/List.razor.cs | 4 + blazor_lab/Pages/_Layout.cshtml | 4 +- blazor_lab/Program.cs | 10 +- blazor_lab/Resources/Pages.List.fr-FR.resx | 123 ++++++++++++++++++ blazor_lab/Resources/Pages.List.resx | 123 ++++++++++++++++++ blazor_lab/Services/DataLocalService.cs | 27 +++- blazor_lab/Services/IDataService.cs | 4 +- blazor_lab/Shared/CultureSelector.razor | 31 +---- blazor_lab/Shared/CultureSelector.razor.cs | 33 +++++ blazor_lab/Shared/NavMenu.razor | 15 --- blazor_lab/Shared/TableTemplate.razor | 28 ++++ .../wwwroot/images/with img this time.png | Bin 15791 -> 0 bytes blazor_lab/wwwroot/images/zdada.png | Bin 15791 -> 0 bytes 35 files changed, 664 insertions(+), 169 deletions(-) create mode 100644 blazor_lab/Components/Crafting.razor create mode 100644 blazor_lab/Components/Crafting.razor.cs create mode 100644 blazor_lab/Components/Crafting.razor.css create mode 100644 blazor_lab/Components/Crafting.razor.js create mode 100644 blazor_lab/Components/CraftingAction.cs create mode 100644 blazor_lab/Components/CraftingItem.razor create mode 100644 blazor_lab/Components/CraftingItem.razor.cs create mode 100644 blazor_lab/Components/CraftingItem.razor.css create mode 100644 blazor_lab/Components/CraftingRecipe.cs delete mode 100644 blazor_lab/Data/WeatherForecast.cs delete mode 100644 blazor_lab/Data/WeatherForecastService.cs create mode 100644 blazor_lab/Models/Cake.cs delete mode 100644 blazor_lab/Pages/Admin/Index.razor delete mode 100644 blazor_lab/Pages/Admin/Users.razor delete mode 100644 blazor_lab/Pages/Admin/_Imports.razor delete mode 100644 blazor_lab/Pages/Counter.razor delete mode 100644 blazor_lab/Pages/FetchData.razor create mode 100644 blazor_lab/Pages/Index.razor.cs create mode 100644 blazor_lab/Resources/Pages.List.fr-FR.resx create mode 100644 blazor_lab/Resources/Pages.List.resx create mode 100644 blazor_lab/Shared/CultureSelector.razor.cs create mode 100644 blazor_lab/Shared/TableTemplate.razor delete mode 100644 blazor_lab/wwwroot/images/with img this time.png delete mode 100644 blazor_lab/wwwroot/images/zdada.png diff --git a/blazor_lab/Components/Crafting.razor b/blazor_lab/Components/Crafting.razor new file mode 100644 index 0000000..65c9b93 --- /dev/null +++ b/blazor_lab/Components/Crafting.razor @@ -0,0 +1,50 @@ + +
+
+
+ +
Available items:
+
+
+ + @foreach (var item in Items) + { + + } +
+
+ +
+ +
+
Recipe
+ +
+ +
+ + + + + + + + + +
+
+ +
Result
+
+ +
+
+ +
+
Actions
+
+
+
+
+
+
\ No newline at end of file diff --git a/blazor_lab/Components/Crafting.razor.cs b/blazor_lab/Components/Crafting.razor.cs new file mode 100644 index 0000000..43a5879 --- /dev/null +++ b/blazor_lab/Components/Crafting.razor.cs @@ -0,0 +1,80 @@ +using blazor_lab.Models; +using Microsoft.AspNetCore.Components; +using Microsoft.JSInterop; +using System.Collections.ObjectModel; +using System.Collections.Specialized; + +namespace blazor_lab.Components +{ + public partial class Crafting + { + private Item _recipeResult; + + public Crafting() + { + Actions = new ObservableCollection(); + Actions.CollectionChanged += OnActionsCollectionChanged; + this.RecipeItems = new List { null, null, null, null, null, null, null, null, null }; + } + + public ObservableCollection Actions { get; set; } + public Item CurrentDragItem { get; set; } + + [Parameter] + public List Items { get; set; } + + public List RecipeItems { get; set; } + + public Item RecipeResult + { + get => this._recipeResult; + set + { + if (this._recipeResult == value) + { + return; + } + + this._recipeResult = value; + this.StateHasChanged(); + } + } + + [Parameter] + public List Recipes { get; set; } + + /// + /// Gets or sets the java script runtime. + /// + [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); + } + } +} diff --git a/blazor_lab/Components/Crafting.razor.css b/blazor_lab/Components/Crafting.razor.css new file mode 100644 index 0000000..2a388f2 --- /dev/null +++ b/blazor_lab/Components/Crafting.razor.css @@ -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; +} diff --git a/blazor_lab/Components/Crafting.razor.js b/blazor_lab/Components/Crafting.razor.js new file mode 100644 index 0000000..d55462f --- /dev/null +++ b/blazor_lab/Components/Crafting.razor.js @@ -0,0 +1,16 @@ +window.Crafting = +{ + AddActions: function (data) { + + data.forEach(element => { + const 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); + }); + } +} \ No newline at end of file diff --git a/blazor_lab/Components/CraftingAction.cs b/blazor_lab/Components/CraftingAction.cs new file mode 100644 index 0000000..80fc59c --- /dev/null +++ b/blazor_lab/Components/CraftingAction.cs @@ -0,0 +1,11 @@ +using blazor_lab.Models; + +namespace blazor_lab.Components +{ + public class CraftingAction + { + public string Action { get; set; } + public int Index { get; set; } + public Item Item { get; set; } + } +} diff --git a/blazor_lab/Components/CraftingItem.razor b/blazor_lab/Components/CraftingItem.razor new file mode 100644 index 0000000..ddf25bf --- /dev/null +++ b/blazor_lab/Components/CraftingItem.razor @@ -0,0 +1,13 @@ +
+ + @if (Item != null) + { + @Item.DisplayName + } +
diff --git a/blazor_lab/Components/CraftingItem.razor.cs b/blazor_lab/Components/CraftingItem.razor.cs new file mode 100644 index 0000000..3a255d2 --- /dev/null +++ b/blazor_lab/Components/CraftingItem.razor.cs @@ -0,0 +1,63 @@ +using blazor_lab.Models; +using Microsoft.AspNetCore.Components; + +namespace blazor_lab.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 }); + } + } +} diff --git a/blazor_lab/Components/CraftingItem.razor.css b/blazor_lab/Components/CraftingItem.razor.css new file mode 100644 index 0000000..b2d4521 --- /dev/null +++ b/blazor_lab/Components/CraftingItem.razor.css @@ -0,0 +1,6 @@ +.item { + width: 64px; + height: 64px; + border: 1px solid; + overflow: hidden; +} diff --git a/blazor_lab/Components/CraftingRecipe.cs b/blazor_lab/Components/CraftingRecipe.cs new file mode 100644 index 0000000..1f32d8b --- /dev/null +++ b/blazor_lab/Components/CraftingRecipe.cs @@ -0,0 +1,10 @@ +using blazor_lab.Models; + +namespace blazor_lab.Components +{ + public class CraftingRecipe + { + public Item Give { get; set; } + public List> Have { get; set; } + } +} diff --git a/blazor_lab/Data/WeatherForecast.cs b/blazor_lab/Data/WeatherForecast.cs deleted file mode 100644 index e0a2391..0000000 --- a/blazor_lab/Data/WeatherForecast.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace blazor_lab.Data -{ - public class WeatherForecast - { - public DateTime Date { get; set; } - - public int TemperatureC { get; set; } - - public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); - - public string? Summary { get; set; } - } -} \ No newline at end of file diff --git a/blazor_lab/Data/WeatherForecastService.cs b/blazor_lab/Data/WeatherForecastService.cs deleted file mode 100644 index 6eab65e..0000000 --- a/blazor_lab/Data/WeatherForecastService.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace blazor_lab.Data -{ - public class WeatherForecastService - { - private static readonly string[] Summaries = new[] - { - "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" - }; - - public Task GetForecastAsync(DateTime startDate) - { - return Task.FromResult(Enumerable.Range(1, 5).Select(index => new WeatherForecast - { - Date = startDate.AddDays(index), - TemperatureC = Random.Shared.Next(-20, 55), - Summary = Summaries[Random.Shared.Next(Summaries.Length)] - }).ToArray()); - } - } -} \ No newline at end of file diff --git a/blazor_lab/Modals/DeleteConfirmation.razor.cs b/blazor_lab/Modals/DeleteConfirmation.razor.cs index 26d6c66..42d57a4 100644 --- a/blazor_lab/Modals/DeleteConfirmation.razor.cs +++ b/blazor_lab/Modals/DeleteConfirmation.razor.cs @@ -1,7 +1,7 @@ using blazor_lab.Models; using blazor_lab.Services; -using Blazored.Modal.Services; using Blazored.Modal; +using Blazored.Modal.Services; using Microsoft.AspNetCore.Components; namespace blazor_lab.Modals diff --git a/blazor_lab/Models/Cake.cs b/blazor_lab/Models/Cake.cs new file mode 100644 index 0000000..b8c9271 --- /dev/null +++ b/blazor_lab/Models/Cake.cs @@ -0,0 +1,9 @@ +namespace blazor_lab.Models +{ + public class Cake + { + public int Id { get; set; } + public string Name { get; set; } + public decimal Cost { get; set; } + } +} diff --git a/blazor_lab/Pages/Add.razor.cs b/blazor_lab/Pages/Add.razor.cs index 6badefb..c1c478f 100644 --- a/blazor_lab/Pages/Add.razor.cs +++ b/blazor_lab/Pages/Add.razor.cs @@ -12,7 +12,7 @@ namespace blazor_lab.Pages public IDataService DataService { get; set; } [Inject] - public NavigationManager NavigationManager { get; set; } + public NavigationManager NavigationManager { get; set; } /// /// The default enchant categories. diff --git a/blazor_lab/Pages/Admin/Index.razor b/blazor_lab/Pages/Admin/Index.razor deleted file mode 100644 index bf98b1c..0000000 --- a/blazor_lab/Pages/Admin/Index.razor +++ /dev/null @@ -1,3 +0,0 @@ -@page "/admin" - -

Index

diff --git a/blazor_lab/Pages/Admin/Users.razor b/blazor_lab/Pages/Admin/Users.razor deleted file mode 100644 index 560b324..0000000 --- a/blazor_lab/Pages/Admin/Users.razor +++ /dev/null @@ -1,2 +0,0 @@ -@page "/admin/users" -

Users

diff --git a/blazor_lab/Pages/Admin/_Imports.razor b/blazor_lab/Pages/Admin/_Imports.razor deleted file mode 100644 index f6c6b4b..0000000 --- a/blazor_lab/Pages/Admin/_Imports.razor +++ /dev/null @@ -1 +0,0 @@ -@layout AdminLayout \ No newline at end of file diff --git a/blazor_lab/Pages/Counter.razor b/blazor_lab/Pages/Counter.razor deleted file mode 100644 index b21f052..0000000 --- a/blazor_lab/Pages/Counter.razor +++ /dev/null @@ -1,18 +0,0 @@ -@page "/counter" - -Counter - -

Counter

- -

Current count: @currentCount

- - - -@code { - private int currentCount = 0; - - private void IncrementCount() - { - currentCount++; - } -} diff --git a/blazor_lab/Pages/FetchData.razor b/blazor_lab/Pages/FetchData.razor deleted file mode 100644 index 6f4b79b..0000000 --- a/blazor_lab/Pages/FetchData.razor +++ /dev/null @@ -1,48 +0,0 @@ -@page "/fetchdata" - -Weather forecast - -@using blazor_lab.Data -@inject WeatherForecastService ForecastService - -

Weather forecast

- -

This component demonstrates fetching data from a service.

- -@if (forecasts == null) -{ -

Loading...

-} -else -{ - - - - - - - - - - - @foreach (var forecast in forecasts) - { - - - - - - - } - -
DateTemp. (C)Temp. (F)Summary
@forecast.Date.ToShortDateString()@forecast.TemperatureC@forecast.TemperatureF@forecast.Summary
-} - -@code { - private WeatherForecast[]? forecasts; - - protected override async Task OnInitializedAsync() - { - forecasts = await ForecastService.GetForecastAsync(DateTime.Now); - } -} diff --git a/blazor_lab/Pages/Index.razor b/blazor_lab/Pages/Index.razor index 0c5b2dd..9941332 100644 --- a/blazor_lab/Pages/Index.razor +++ b/blazor_lab/Pages/Index.razor @@ -1,13 +1,16 @@ @page "/" @using System.Globalization; +@using Microsoft.AspNetCore.Components; +@using blazor_lab.Models +@using blazor_lab.Components Index -

Hello, world!

+

Crafty McCraftFace

-Welcome to your new app. - - +
+ +

CurrentCulture: @CultureInfo.CurrentCulture diff --git a/blazor_lab/Pages/Index.razor.cs b/blazor_lab/Pages/Index.razor.cs new file mode 100644 index 0000000..e98210a --- /dev/null +++ b/blazor_lab/Pages/Index.razor.cs @@ -0,0 +1,32 @@ +using blazor_lab.Components; +using blazor_lab.Models; +using blazor_lab.Services; +using Microsoft.AspNetCore.Components; + +namespace blazor_lab.Pages +{ + public partial class Index + { + [Inject] + public IDataService DataService { get; set; } + + public List Items { get; set; } = new List(); + + private List Recipes { get; set; } = new List(); + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + base.OnAfterRenderAsync(firstRender); + + if (!firstRender) + { + return; + } + + Items = await DataService.List(0, await DataService.Count()); + Recipes = await DataService.GetRecipes(); + + StateHasChanged(); + } + } +} diff --git a/blazor_lab/Pages/List.razor b/blazor_lab/Pages/List.razor index 90d945b..c714550 100644 --- a/blazor_lab/Pages/List.razor +++ b/blazor_lab/Pages/List.razor @@ -1,7 +1,7 @@ @page "/list" @using Models -

List

+

@Localizer["Title"]

diff --git a/blazor_lab/Pages/List.razor.cs b/blazor_lab/Pages/List.razor.cs index ab6c643..a8e3c87 100644 --- a/blazor_lab/Pages/List.razor.cs +++ b/blazor_lab/Pages/List.razor.cs @@ -5,6 +5,7 @@ using Blazored.Modal; using Blazored.Modal.Services; using Blazorise.DataGrid; using Microsoft.AspNetCore.Components; +using Microsoft.Extensions.Localization; namespace blazor_lab.Pages { @@ -14,6 +15,9 @@ namespace blazor_lab.Pages private int totalItems; + [Inject] + public IStringLocalizer Localizer { get; set; } + [Inject] public IDataService DataService { get; set; } diff --git a/blazor_lab/Pages/_Layout.cshtml b/blazor_lab/Pages/_Layout.cshtml index 44f8e88..26c864a 100644 --- a/blazor_lab/Pages/_Layout.cshtml +++ b/blazor_lab/Pages/_Layout.cshtml @@ -29,8 +29,10 @@ + - + + diff --git a/blazor_lab/Program.cs b/blazor_lab/Program.cs index 77f6d67..259e4b8 100644 --- a/blazor_lab/Program.cs +++ b/blazor_lab/Program.cs @@ -1,20 +1,18 @@ -using blazor_lab.Data; +using blazor_lab.Services; +using Blazored.LocalStorage; +using Blazored.Modal; using Blazorise; using Blazorise.Bootstrap; using Blazorise.Icons.FontAwesome; -using Blazored.LocalStorage; -using blazor_lab.Services; -using Blazored.Modal; using Microsoft.AspNetCore.Localization; -using System.Globalization; using Microsoft.Extensions.Options; +using System.Globalization; var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddRazorPages(); builder.Services.AddServerSideBlazor(); -builder.Services.AddSingleton(); builder.Services.AddHttpClient(); diff --git a/blazor_lab/Resources/Pages.List.fr-FR.resx b/blazor_lab/Resources/Pages.List.fr-FR.resx new file mode 100644 index 0000000..50bb302 --- /dev/null +++ b/blazor_lab/Resources/Pages.List.fr-FR.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Liste des éléments + + \ No newline at end of file diff --git a/blazor_lab/Resources/Pages.List.resx b/blazor_lab/Resources/Pages.List.resx new file mode 100644 index 0000000..a8fea6f --- /dev/null +++ b/blazor_lab/Resources/Pages.List.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Items list + + \ No newline at end of file diff --git a/blazor_lab/Services/DataLocalService.cs b/blazor_lab/Services/DataLocalService.cs index 7c097f7..77556ef 100644 --- a/blazor_lab/Services/DataLocalService.cs +++ b/blazor_lab/Services/DataLocalService.cs @@ -1,8 +1,8 @@ -using blazor_lab.Factories; +using blazor_lab.Components; +using blazor_lab.Factories; using blazor_lab.Models; using Blazored.LocalStorage; using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.Hosting; namespace blazor_lab.Services { @@ -83,7 +83,7 @@ namespace blazor_lab.Services var imagePathInfo = new DirectoryInfo($"{_webHostEnvironment.WebRootPath}/images"); var fileInfo = new FileInfo($"{imagePathInfo}/{item.Name}.png"); - if(fileInfo.Exists) + if (fileInfo.Exists) { File.Delete(fileInfo.FullName); } @@ -103,6 +103,25 @@ namespace blazor_lab.Services return item; } + public Task> GetRecipes() + { + var items = new List + { + new CraftingRecipe + { + Give = new Item { DisplayName = "Diamond", Name = "diamond" }, + Have = new List> + { + new List { "dirt", "dirt", "dirt" }, + new List { "dirt", null, "dirt" }, + new List { "dirt", "dirt", "dirt" } + } + } + }; + + return Task.FromResult(items); + } + public async Task> List(int currentPage, int pageSize) { if (await _localStorageService.GetItemAsync("data") == null) @@ -138,7 +157,7 @@ namespace blazor_lab.Services ItemFactory.Update(item, model); - await _localStorageService.SetItemAsync("data", currentData); + await _localStorageService.SetItemAsync("data", currentData); } } } diff --git a/blazor_lab/Services/IDataService.cs b/blazor_lab/Services/IDataService.cs index 9f4572f..4691503 100644 --- a/blazor_lab/Services/IDataService.cs +++ b/blazor_lab/Services/IDataService.cs @@ -1,4 +1,5 @@ -using blazor_lab.Models; +using blazor_lab.Components; +using blazor_lab.Models; namespace blazor_lab.Services { @@ -10,5 +11,6 @@ namespace blazor_lab.Services Task GetById(int id); Task Update(int id, ItemModel model); Task Delete(int id); + Task> GetRecipes(); } } diff --git a/blazor_lab/Shared/CultureSelector.razor b/blazor_lab/Shared/CultureSelector.razor index 6d7f012..0bb1037 100644 --- a/blazor_lab/Shared/CultureSelector.razor +++ b/blazor_lab/Shared/CultureSelector.razor @@ -11,33 +11,4 @@ } -

- -@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); - } - } -} \ No newline at end of file +

\ No newline at end of file diff --git a/blazor_lab/Shared/CultureSelector.razor.cs b/blazor_lab/Shared/CultureSelector.razor.cs new file mode 100644 index 0000000..e73bdc1 --- /dev/null +++ b/blazor_lab/Shared/CultureSelector.razor.cs @@ -0,0 +1,33 @@ +using System.Globalization; + +namespace blazor_lab.Shared +{ + public partial class CultureSelector + { + 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); + } + } + } +} diff --git a/blazor_lab/Shared/NavMenu.razor b/blazor_lab/Shared/NavMenu.razor index e9baf2f..8c9d622 100644 --- a/blazor_lab/Shared/NavMenu.razor +++ b/blazor_lab/Shared/NavMenu.razor @@ -20,21 +20,6 @@ Home
- - - diff --git a/blazor_lab/Shared/TableTemplate.razor b/blazor_lab/Shared/TableTemplate.razor new file mode 100644 index 0000000..72c3ae5 --- /dev/null +++ b/blazor_lab/Shared/TableTemplate.razor @@ -0,0 +1,28 @@ +@typeparam TItem +@using System.Diagnostics.CodeAnalysis + + + + @TableHeader + + + @foreach (var item in Items) + { + if (RowTemplate is not null) + { + @RowTemplate(item) + } + } + +
+ +@code { + [Parameter] + public RenderFragment? TableHeader { get; set; } + + [Parameter] + public RenderFragment? RowTemplate { get; set; } + + [Parameter, AllowNull] + public IReadOnlyList Items { get; set; } +} \ No newline at end of file diff --git a/blazor_lab/wwwroot/images/with img this time.png b/blazor_lab/wwwroot/images/with img this time.png deleted file mode 100644 index 989ea6a559d70d4557ffa8c8f70fd64dac5dc94d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15791 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 R3mCG7Q;<=Su8}kg{%^&Ie?R~L diff --git a/blazor_lab/wwwroot/images/zdada.png b/blazor_lab/wwwroot/images/zdada.png deleted file mode 100644 index 989ea6a559d70d4557ffa8c8f70fd64dac5dc94d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15791 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 R3mCG7Q;<=Su8}kg{%^&Ie?R~L