Skip to content

Commit

Permalink
feat(apps): Blazor AutoMode demo
Browse files Browse the repository at this point in the history
  • Loading branch information
SonicGD committed Jan 12, 2024
1 parent 6b75b83 commit 6a3e325
Show file tree
Hide file tree
Showing 42 changed files with 1,231 additions and 0 deletions.
45 changes: 45 additions & 0 deletions Sitko.Core.sln
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Blazor", "Blazor", "{0CD96A
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MudBlazorUnited", "apps\Blazor\MudBlazorUnited\MudBlazorUnited.csproj", "{AA9D56AD-4BC2-48A5-AF79-B6019415C5C9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MudBlazorAuto", "apps\Blazor\MudBlazorAuto\MudBlazorAuto.csproj", "{1FDA9560-CDF6-4CF9-86FA-F03BF4AE373F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MudBlazorAuto.Client", "apps\Blazor\MudBlazorAuto.Client\MudBlazorAuto.Client.csproj", "{BBFB3B40-213F-49AF-B12A-38EDA1425BE3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MudBlazorAuto.Data", "apps\Blazor\MudBlazorAuto.Data\MudBlazorAuto.Data.csproj", "{5131E964-D2FB-4DE4-B968-6C85EFF9092D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -1443,6 +1449,42 @@ Global
{AA9D56AD-4BC2-48A5-AF79-B6019415C5C9}.Release|x64.Build.0 = Release|Any CPU
{AA9D56AD-4BC2-48A5-AF79-B6019415C5C9}.Release|x86.ActiveCfg = Release|Any CPU
{AA9D56AD-4BC2-48A5-AF79-B6019415C5C9}.Release|x86.Build.0 = Release|Any CPU
{1FDA9560-CDF6-4CF9-86FA-F03BF4AE373F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1FDA9560-CDF6-4CF9-86FA-F03BF4AE373F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1FDA9560-CDF6-4CF9-86FA-F03BF4AE373F}.Debug|x64.ActiveCfg = Debug|Any CPU
{1FDA9560-CDF6-4CF9-86FA-F03BF4AE373F}.Debug|x64.Build.0 = Debug|Any CPU
{1FDA9560-CDF6-4CF9-86FA-F03BF4AE373F}.Debug|x86.ActiveCfg = Debug|Any CPU
{1FDA9560-CDF6-4CF9-86FA-F03BF4AE373F}.Debug|x86.Build.0 = Debug|Any CPU
{1FDA9560-CDF6-4CF9-86FA-F03BF4AE373F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1FDA9560-CDF6-4CF9-86FA-F03BF4AE373F}.Release|Any CPU.Build.0 = Release|Any CPU
{1FDA9560-CDF6-4CF9-86FA-F03BF4AE373F}.Release|x64.ActiveCfg = Release|Any CPU
{1FDA9560-CDF6-4CF9-86FA-F03BF4AE373F}.Release|x64.Build.0 = Release|Any CPU
{1FDA9560-CDF6-4CF9-86FA-F03BF4AE373F}.Release|x86.ActiveCfg = Release|Any CPU
{1FDA9560-CDF6-4CF9-86FA-F03BF4AE373F}.Release|x86.Build.0 = Release|Any CPU
{BBFB3B40-213F-49AF-B12A-38EDA1425BE3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BBFB3B40-213F-49AF-B12A-38EDA1425BE3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BBFB3B40-213F-49AF-B12A-38EDA1425BE3}.Debug|x64.ActiveCfg = Debug|Any CPU
{BBFB3B40-213F-49AF-B12A-38EDA1425BE3}.Debug|x64.Build.0 = Debug|Any CPU
{BBFB3B40-213F-49AF-B12A-38EDA1425BE3}.Debug|x86.ActiveCfg = Debug|Any CPU
{BBFB3B40-213F-49AF-B12A-38EDA1425BE3}.Debug|x86.Build.0 = Debug|Any CPU
{BBFB3B40-213F-49AF-B12A-38EDA1425BE3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BBFB3B40-213F-49AF-B12A-38EDA1425BE3}.Release|Any CPU.Build.0 = Release|Any CPU
{BBFB3B40-213F-49AF-B12A-38EDA1425BE3}.Release|x64.ActiveCfg = Release|Any CPU
{BBFB3B40-213F-49AF-B12A-38EDA1425BE3}.Release|x64.Build.0 = Release|Any CPU
{BBFB3B40-213F-49AF-B12A-38EDA1425BE3}.Release|x86.ActiveCfg = Release|Any CPU
{BBFB3B40-213F-49AF-B12A-38EDA1425BE3}.Release|x86.Build.0 = Release|Any CPU
{5131E964-D2FB-4DE4-B968-6C85EFF9092D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5131E964-D2FB-4DE4-B968-6C85EFF9092D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5131E964-D2FB-4DE4-B968-6C85EFF9092D}.Debug|x64.ActiveCfg = Debug|Any CPU
{5131E964-D2FB-4DE4-B968-6C85EFF9092D}.Debug|x64.Build.0 = Debug|Any CPU
{5131E964-D2FB-4DE4-B968-6C85EFF9092D}.Debug|x86.ActiveCfg = Debug|Any CPU
{5131E964-D2FB-4DE4-B968-6C85EFF9092D}.Debug|x86.Build.0 = Debug|Any CPU
{5131E964-D2FB-4DE4-B968-6C85EFF9092D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5131E964-D2FB-4DE4-B968-6C85EFF9092D}.Release|Any CPU.Build.0 = Release|Any CPU
{5131E964-D2FB-4DE4-B968-6C85EFF9092D}.Release|x64.ActiveCfg = Release|Any CPU
{5131E964-D2FB-4DE4-B968-6C85EFF9092D}.Release|x64.Build.0 = Release|Any CPU
{5131E964-D2FB-4DE4-B968-6C85EFF9092D}.Release|x86.ActiveCfg = Release|Any CPU
{5131E964-D2FB-4DE4-B968-6C85EFF9092D}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{6677865F-C349-4D25-9E19-3DEC43E92DD5} = {109B331E-71B9-483C-8FC1-13B10C92A7F1}
Expand Down Expand Up @@ -1546,5 +1588,8 @@ Global
{5D438687-8576-425A-A8A9-A80B893DCE0C} = {109B331E-71B9-483C-8FC1-13B10C92A7F1}
{0CD96A05-3892-4A9E-8768-C00B3ADF84CF} = {F626F7B7-70BB-4D3B-A803-68ADA8BA4234}
{AA9D56AD-4BC2-48A5-AF79-B6019415C5C9} = {0CD96A05-3892-4A9E-8768-C00B3ADF84CF}
{1FDA9560-CDF6-4CF9-86FA-F03BF4AE373F} = {0CD96A05-3892-4A9E-8768-C00B3ADF84CF}
{BBFB3B40-213F-49AF-B12A-38EDA1425BE3} = {0CD96A05-3892-4A9E-8768-C00B3ADF84CF}
{5131E964-D2FB-4DE4-B968-6C85EFF9092D} = {0CD96A05-3892-4A9E-8768-C00B3ADF84CF}
EndGlobalSection
EndGlobal
2 changes: 2 additions & 0 deletions apps/Blazor/MudBlazorAuto.Client/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
wwwroot/static
!.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using MudBlazorAuto.Data.Entities;
using Sitko.Core.Blazor.MudBlazorComponents;
using Sitko.Core.Repository;

namespace MudBlazorAuto.Client.Components.Lists
{
public class BarRepositoryList : MudRepositoryTable<BarModel, Guid, IRepository<BarModel, Guid>>
{
public Task UpdateAsync(BarModel barModel) =>
ExecuteRepositoryOperation(async repository =>
{
barModel.Date = DateTimeOffset.UtcNow;
var result = await repository.UpdateAsync(barModel);
return result.IsSuccess;
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@inherits BaseComponent
<h3>TestComponent</h3>

@code {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using MudBlazorAuto.Data.Entities;
using Sitko.Core.Repository.Remote;

namespace MudBlazorAuto.Client.Data.Repositories;

public class BarModelRemoteRepository : BaseRemoteRepository<BarModel, Guid>
{
public BarModelRemoteRepository(RemoteRepositoryContext<BarModel, Guid> repositoryContext) : base(repositoryContext)
{
}
}
20 changes: 20 additions & 0 deletions apps/Blazor/MudBlazorAuto.Client/MudBlazorAuto.Client.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<NoDefaultLaunchSettingsFile>true</NoDefaultLaunchSettingsFile>
<StaticWebAssetProjectMode>Default</StaticWebAssetProjectMode>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\src\Sitko.Core.Blazor.MudBlazor\Sitko.Core.Blazor.MudBlazor.csproj" />
<ProjectReference Include="..\..\..\src\Sitko.Core.Blazor.Wasm\Sitko.Core.Blazor.Wasm.csproj" />
<ProjectReference Include="..\..\..\src\Sitko.Core.Repository.Remote.Wasm\Sitko.Core.Repository.Remote.Wasm.csproj" />
<ProjectReference Include="..\..\..\src\Sitko.Core.Storage.Remote\Sitko.Core.Storage.Remote.csproj" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.0-rc.2.23480.2" />
<ProjectReference Include="..\MudBlazorAuto.Data\MudBlazorAuto.Data.csproj" />
</ItemGroup>

</Project>
60 changes: 60 additions & 0 deletions apps/Blazor/MudBlazorAuto.Client/Pages/Index.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
@page "/"
@using MudBlazorAuto.Data.Entities
@attribute [RenderModeInteractiveWebAssembly]
@inherits BaseComponent

<MudGrid>
<MudItem xs="6" sm="4">
<MudAutocomplete @ref="IdFilterAutocomplete" T="BarModel" Label="ID" SearchFunc="@SearchIdsAsync" ResetValueOnEmptyText="true"
Value="FilterList.Model"
ToStringFunc="@(e => e == null ? null : $"{e.Bar}")"
ValueChanged="@(s => ChangeIdAsync(s == null ? null : s.Id))"/>
</MudItem>

<MudItem xs="6" sm="4">
<MudTextField T="string" Value="FilterList.Title" Label="Title" ValueChanged="SearchTitleAsync" Class="mt-0" Clearable="true">
</MudTextField>
</MudItem>

<MudItem xs="12" sm="4">
<MudDateRangePicker DateRange="FilterList.DateRange" Label="Дата" PickerVariant="PickerVariant.Dialog" DateRangeChanged="@(dateRange => ChangeDateAsync(dateRange))"/>
</MudItem>
</MudGrid>

<MudPageLayout Title="@LocalizationProvider["Title"]">
<BarRepositoryList @bind-RowsPerPage="rowsPerPage" OnDataLoaded="CountSummaryAsync" @ref="barList" Class="mb-10" EnableUrlNavigation="true"
ConfigureQuery="ConfigureQueryAsync" AddParamsToUrl="AddParamsToUrlAsync"
GetParamsFromUrl="GetParamsFromUrlAsync">
<HeaderContent>
<MudTh>
<MudTableSortLabel SortLabel="@nameof(BarModel.Id)" InitialDirection="SortDirection.Descending" T="BarModel">Id</MudTableSortLabel>
</MudTh>
<MudTh>
<MudTableSortLabel SortLabel="@nameof(BarModel.Bar)" T="BarModel">Название</MudTableSortLabel>
</MudTh>
<MudTh>
<MudTableSortLabel SortLabel="@nameof(BarModel.Date)" T="BarModel">Дата</MudTableSortLabel>
</MudTh>
<MudTh></MudTh>
</HeaderContent>
<ChildContent>
<MudTd DataLabel="@nameof(BarModel.Id)">
<MudLink Href="@($"/Bars/{context.Id}/Edit")">@context.Id</MudLink>
</MudTd>
<MudTd DataLabel="@nameof(BarModel.Bar)">
@context.Bar
</MudTd>
<MudTd DataLabel="@nameof(BarModel.Date)">
@context.Date
</MudTd>
<MudTd>
<MudButton Variant="Variant.Outlined" Color="Color.Secondary" Size="Size.Small" StartIcon="@Icons.Material.Filled.Refresh" OnClick="@(() => barList.UpdateAsync(context))">Refresh</MudButton>
</MudTd>
</ChildContent>
<FooterContent>
<MudTFootRow Class="bold-text">
<MudTd>@Summary</MudTd>
</MudTFootRow>
</FooterContent>
</BarRepositoryList>
</MudPageLayout>
157 changes: 157 additions & 0 deletions apps/Blazor/MudBlazorAuto.Client/Pages/Index.razor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
using System.Globalization;
using Microsoft.AspNetCore.Components;
using MudBlazor;
using MudBlazorAuto.Client.Components.Lists;
using MudBlazorAuto.Data.Entities;
using Sitko.Core.Blazor.MudBlazorComponents;
using Sitko.Core.Repository;

namespace MudBlazorAuto.Client.Pages
{
public partial class Index
{
private int rowsPerPage = 10;
private const string FilterParamId = "id";
private const string FilterParamTitle = "title";
private const string FilterParamDateRange = "dateRange";

[Parameter]
[SupplyParameterFromQuery(Name = FilterParamId)]
public Guid? Id { get; set; }

[Parameter]
[SupplyParameterFromQuery(Name = FilterParamTitle)]
public string? Title { get; set; }

[Parameter]
[SupplyParameterFromQuery(Name = FilterParamDateRange)]
public string? DateRange { get; set; }

private BarRepositoryList barList = null!;
private decimal Summary { get; set; }

private async Task CountSummaryAsync(TableState state, MudTableFilter filter) =>
Summary = await barList.SumAsync(model => model.Sum);

private FilterList FilterList { get; set; } = new();
private MudAutocomplete<BarModel> IdFilterAutocomplete { get; set; } = null!;

[Inject] private IRepository<BarModel, Guid> BarRepository { get; set; } = null!;
private (BarModel[] items, int itemsCount) bars;

protected override async Task InitializeAsync()
{
await base.InitializeAsync();
bars = await BarRepository.GetAllAsync();
}

private async Task<IEnumerable<BarModel>> SearchIdsAsync(string? value) => string.IsNullOrEmpty(value)
? (await BarRepository.GetAllAsync()).items
: (await BarRepository.GetAllAsync(q => q.Where(b => b.Id == Guid.Parse(value)))).items;

private async Task ChangeDateAsync(DateRange? dateRange)
{
FilterList.DateRange = dateRange;
await barList.RefreshAsync();
}

private async Task ChangeIdAsync(Guid? id)
{
FilterList.Model = bars.items.FirstOrDefault(b => id != null && b.Id == id);
await IdFilterAutocomplete.ToggleMenu();
await barList.RefreshAsync();
}

private async Task SearchTitleAsync(string value)
{
FilterList.Title = value;
await barList.RefreshAsync();
}

private Task ConfigureQueryAsync(IRepositoryQuery<BarModel> query)
{
query.Where(model => model.Bar != "");
if (FilterList.Model is not null && FilterList.Model.Id != Guid.Empty)
{
query.Where(p => p.Id == FilterList.Model.Id);
}

if (!string.IsNullOrEmpty(FilterList.Title))
{
query.Where(p => p.Bar == FilterList.Title);
}

if (FilterList.DateRange is not null)
{
query.Where(p => p.Date >= new DateTimeOffset((DateTime)FilterList.DateRange.Start!).UtcDateTime &&
p.Date <= new DateTimeOffset((DateTime)FilterList.DateRange.End!).UtcDateTime);
}

return Task.CompletedTask;
}

private Task<Dictionary<string, object?>> AddParamsToUrlAsync()
{
var urlParams = new Dictionary<string, object?>();
urlParams.Add(FilterParamId, FilterList.Model?.Id);
urlParams.Add(FilterParamTitle, FilterList.Title);
if (FilterList.DateRange != null)
{
urlParams.Add(FilterParamDateRange,
$"{FilterList.DateRange.Start.ToString()}-{FilterList.DateRange.End.ToString()}");
}
else
{
urlParams.Add(FilterParamDateRange, null);
}

return Task.FromResult(urlParams);
}

private Task GetParamsFromUrlAsync()
{
var hasChanged = false;
if (Id != null)
{
FilterList.Model = bars.items.FirstOrDefault(b => b.Id == Id);
hasChanged = true;
}

if (!string.IsNullOrEmpty(Title))
{
FilterList.Title = Title;
hasChanged = true;
}

if (!string.IsNullOrEmpty(DateRange))
{
var dateData = DateRange.Split("-");
if (dateData.Length == 2)
{
FilterList.DateRange = new DateRange(DateTime.Parse(dateData[0], CultureInfo.InvariantCulture),
DateTime.Parse(dateData[1], CultureInfo.InvariantCulture));
hasChanged = true;
}
}

if (hasChanged)
{
StateHasChanged();
}

return Task.CompletedTask;
}
}

public class BarStorageMetadata
{
public Guid Id { get; set; } = Guid.NewGuid();
}

public class FilterList
{
public BarModel? Model { get; set; }
public string? Title { get; set; }
public DateRange? DateRange { get; set; }
}
}
33 changes: 33 additions & 0 deletions apps/Blazor/MudBlazorAuto.Client/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Sitko.Core.App.Localization;
using Sitko.Core.Blazor.MudBlazorComponents;
using Sitko.Core.Blazor.Wasm;
using Sitko.Core.Repository.Remote;
using Sitko.Core.Repository.Remote.Wasm;
using Sitko.Core.Storage;
using Sitko.Core.Storage.Remote;
using Index = MudBlazorAuto.Client.Pages.Index;

var builder = WebAssemblyHostBuilder.CreateDefault(args);

builder
.AddSitkoCore()
.AddMudBlazor()
.AddJsonLocalization(options => options.AddDefaultResource<Index>())
.AddRemoteRepositories(options => options.AddRepositoriesFromAssemblyOf<Program>())
.AddWasmHttpRepositoryTransport(options =>
{
options.RepositoryControllerApiRoute = new Uri("https://localhost:7163/api");
});

builder.Services
.AddHttpClient(nameof(HttpRepositoryTransport)).AddHttpMessageHandler<CookieHandler>();
builder.Services.AddScoped(_ => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });

await builder.Build().RunAsync();

public class TestRemoteStorageOptions : StorageOptions, IRemoteStorageOptions
{
public Uri RemoteUrl { get; set; } = new("https://localhost");
public Func<HttpClient>? HttpClientFactory { get; set; }
}
15 changes: 15 additions & 0 deletions apps/Blazor/MudBlazorAuto.Client/_Imports.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
@using System.Net.Http
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.JSInterop
@using MudBlazorAuto.Client
@using MudBlazorAuto.Client.Components
@using MudBlazorAuto.Client.Components.Lists
@using Sitko.Core.Blazor.Components
@using Sitko.Core.Blazor.MudBlazorComponents
@using Sitko.Core.App.Collections
@using Sitko.Core.Storage
@using MudBlazor
Loading

0 comments on commit 6a3e325

Please sign in to comment.