Skip to content

Commit 88a199e

Browse files
committed
Add CQRS sample frontend
1 parent 408cc15 commit 88a199e

13 files changed

+271
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
4+
<head>
5+
<meta charset="utf-8" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<base href="/" />
8+
9+
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" rel="stylesheet" />
10+
<link href="_content/MudBlazor/MudBlazor.min.css" rel="stylesheet" />
11+
12+
13+
<link rel="icon" type="image/png" href="favicon.ico" />
14+
<HeadOutlet @rendermode="@InteractiveServer" />
15+
</head>
16+
17+
<body>
18+
<Routes @rendermode="@InteractiveServer" />
19+
<script src="_framework/blazor.web.js"></script>
20+
<script src="_content/MudBlazor/MudBlazor.min.js"></script>
21+
</body>
22+
23+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
@inherits LayoutComponentBase
2+
3+
<MudThemingProvider />
4+
<MudPopoverProvider />
5+
<MudDialogProvider />
6+
<MudSnackbarProvider />
7+
8+
<MudLayout>
9+
<MudAppBar Elevation="1">
10+
<MudText Typo="Typo.h5" Class="ml-3">Akka.NET SqlServer CQRS Demo</MudText>
11+
</MudAppBar>
12+
<MudMainContent Class="mt-16 pa-4">
13+
@Body
14+
</MudMainContent>
15+
</MudLayout>
16+
17+
@code {
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
@page "/Error"
2+
@using System.Diagnostics
3+
4+
<PageTitle>Error</PageTitle>
5+
6+
<h1 class="text-danger">Error.</h1>
7+
<h2 class="text-danger">An error occurred while processing your request.</h2>
8+
9+
@if (ShowRequestId)
10+
{
11+
<p>
12+
<strong>Request ID:</strong> <code>@RequestId</code>
13+
</p>
14+
}
15+
16+
<h3>Development Mode</h3>
17+
<p>
18+
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
19+
</p>
20+
<p>
21+
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
22+
It can result in displaying sensitive information from exceptions to end users.
23+
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
24+
and restarting the app.
25+
</p>
26+
27+
@code{
28+
[CascadingParameter]
29+
private HttpContext? HttpContext { get; set; }
30+
31+
private string? RequestId { get; set; }
32+
private bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
33+
34+
protected override void OnInitialized() =>
35+
RequestId = Activity.Current?.Id ?? HttpContext?.TraceIdentifier;
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
@page "/"
2+
@using CqrsSqlServer.DataModel.Entities
3+
@using CqrsSqlServer.DataModel
4+
@using Microsoft.EntityFrameworkCore
5+
@inject CqrsSqlServerContext DbContext
6+
7+
<PageTitle>Product Data</PageTitle>
8+
<div class="d-flex flex-grow-1 gap-4">
9+
<MudText Typo="Typo.h3" GutterBottom="true">Product Data</MudText>
10+
<MudFab Color="Color.Primary" StartIcon="@Icons.Material.Filled.Refresh" OnClick="RefreshCallback"></MudFab>
11+
</div>
12+
13+
<MudTable Items="_products" Hover="true" SortLabel="Sort By" Elevation="0" Loading="@_loading">
14+
<HeaderContent>
15+
<MudTh><MudTableSortLabel InitialDirection="SortDirection.Ascending" SortBy="new Func<ProductListing, object>(x=>x.ProductId)">Id</MudTableSortLabel></MudTh>
16+
<MudTh><MudTableSortLabel SortBy="new Func<ProductListing, object>(x=>x.ProductName)">Name</MudTableSortLabel></MudTh>
17+
<MudTh><MudTableSortLabel SortBy="new Func<ProductListing, object>(x=>x.Price)">Price</MudTableSortLabel></MudTh>
18+
<MudTh><MudTableSortLabel SortBy="new Func<ProductListing, object>(x=>x.AllInventory)">Inventory</MudTableSortLabel></MudTh>
19+
<MudTh><MudTableSortLabel SortBy="new Func<ProductListing, object>(x=>x.SoldUnits)">Sold</MudTableSortLabel></MudTh>
20+
<MudTh><MudTableSortLabel SortBy="new Func<ProductListing, object>(x=>x.TotalRevenue)">Revenue</MudTableSortLabel></MudTh>
21+
<MudTh><MudTableSortLabel SortBy="new Func<ProductListing, object>(x=>x.Created)">Created</MudTableSortLabel></MudTh>
22+
<MudTh><MudTableSortLabel SortBy="new Func<ProductListing, object>(x=>x.LastModified)">Updated</MudTableSortLabel></MudTh>
23+
</HeaderContent>
24+
<RowTemplate>
25+
<MudTd DataLabel="Id">@context.ProductId</MudTd>
26+
<MudTd DataLabel="Name">@context.ProductName</MudTd>
27+
<MudTd DataLabel="Price">@context.Price</MudTd>
28+
<MudTd DataLabel="Inventory">@context.AllInventory</MudTd>
29+
<MudTd DataLabel="Sold">@context.SoldUnits</MudTd>
30+
<MudTd DataLabel="Revenue">@context.TotalRevenue</MudTd>
31+
<MudTd DataLabel="Created">@context.Created</MudTd>
32+
<MudTd DataLabel="Updated">@context.LastModified</MudTd>
33+
</RowTemplate>
34+
<PagerContent>
35+
<MudTablePager PageSizeOptions="new int[]{10, 50, 100}" />
36+
</PagerContent>
37+
</MudTable>
38+
39+
@code {
40+
private ProductListing[] _products = Array.Empty<ProductListing>();
41+
private bool _loading = true;
42+
43+
protected override async Task OnInitializedAsync()
44+
{
45+
_products = await DbContext.Products.ToArrayAsync();
46+
_loading = false;
47+
}
48+
49+
private async Task RefreshCallback()
50+
{
51+
_loading = true;
52+
StateHasChanged();
53+
_products = await DbContext.Products.ToArrayAsync();
54+
_loading = false;
55+
StateHasChanged();
56+
}
57+
58+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<Router AppAssembly="@typeof(Program).Assembly">
2+
<Found Context="routeData">
3+
<RouteView RouteData="@routeData" DefaultLayout="@typeof(Layout.MainLayout)" />
4+
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
5+
</Found>
6+
</Router>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
@using System.Net.Http
2+
@using System.Net.Http.Json
3+
@using Microsoft.AspNetCore.Components.Forms
4+
@using Microsoft.AspNetCore.Components.Routing
5+
@using Microsoft.AspNetCore.Components.Web
6+
@using static Microsoft.AspNetCore.Components.Web.RenderMode
7+
@using Microsoft.AspNetCore.Components.Web.Virtualization
8+
@using Microsoft.JSInterop
9+
@using CqrsSqlServer.Frontend
10+
@using CqrsSqlServer.Frontend.Components
11+
@using MudBlazor
12+
@using MudBlazor.Services
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<Project Sdk="Microsoft.NET.Sdk.Web">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net8.0</TargetFramework>
5+
<Nullable>enable</Nullable>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
</PropertyGroup>
8+
9+
10+
<ItemGroup>
11+
<PackageReference Include="MudBlazor" Version="6.*" />
12+
</ItemGroup>
13+
14+
15+
<ItemGroup>
16+
<ProjectReference Include="..\CqrsSqlServer.DataModel\CqrsSqlServer.DataModel.csproj" />
17+
</ItemGroup>
18+
19+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
using CqrsSqlServer.DataModel;
2+
using CqrsSqlServer.Frontend.Components;
3+
using Microsoft.EntityFrameworkCore;
4+
using MudBlazor.Services;
5+
6+
namespace CqrsSqlServer.Frontend;
7+
8+
public class Program
9+
{
10+
public static void Main(string[] args)
11+
{
12+
var builder = WebApplication.CreateBuilder(args);
13+
14+
// Add services to the container.
15+
builder.Services.AddRazorComponents()
16+
.AddInteractiveServerComponents();
17+
18+
builder.Services.AddMudServices();
19+
20+
var connectionString = builder.Configuration.GetConnectionString("AkkaSqlConnection");
21+
if (connectionString is null)
22+
throw new Exception("AkkaSqlConnection setting is missing");
23+
24+
builder.Services.AddDbContext<CqrsSqlServerContext>(options =>
25+
{
26+
// disable change tracking for all implementations of this context
27+
options.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
28+
options.UseSqlServer(connectionString);
29+
});
30+
31+
var app = builder.Build();
32+
33+
// Configure the HTTP request pipeline.
34+
if (!app.Environment.IsDevelopment())
35+
{
36+
app.UseExceptionHandler("/Error");
37+
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
38+
app.UseHsts();
39+
}
40+
41+
app.UseHttpsRedirection();
42+
43+
app.UseStaticFiles();
44+
app.UseAntiforgery();
45+
46+
app.MapRazorComponents<App>()
47+
.AddInteractiveServerRenderMode();
48+
49+
app.Run();
50+
}
51+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"Logging": {
3+
"LogLevel": {
4+
"Default": "Information",
5+
"Microsoft.AspNetCore": "Warning"
6+
}
7+
}
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"Logging": {
3+
"LogLevel": {
4+
"Default": "Information",
5+
"Microsoft.AspNetCore": "Warning"
6+
}
7+
},
8+
"AllowedHosts": "*",
9+
"ConnectionStrings": {
10+
"AkkaSqlConnection": "Server=localhost,1533; Database=Akka; User Id=sa; Password=yourStrong(!)Password; TrustServerCertificate=true;"
11+
}
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
This CSS file matches the color scheme from MudBlazor to Bootstrap when utilized for authentication.
3+
The file remains available at all times for demonstration purposes,
4+
but it is exclusively employed in the 'App.razor' component when authentication is enabled.
5+
*/
6+
7+
.btn-primary {
8+
text-transform: uppercase;
9+
--bs-btn-bg: var(--mud-palette-primary) !important;
10+
--bs-btn-hover-bg: var(--mud-palette-primary-darken) !important;
11+
}
12+
13+
.nav-pills {
14+
--bs-nav-pills-link-active-bg: var(--mud-palette-primary) !important;
15+
}
16+
17+
.nav {
18+
--bs-nav-link-color: var(--mud-palette-primary) !important;
19+
--bs-nav-link-hover-color: var(--mud-palette-primary-darken) !important;
20+
}
Binary file not shown.

src/cqrs/cqrs-sqlserver/CqrsSqlServer.sln

+8
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CqrsSqlServer.Backend", "Cq
99
EndProject
1010
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CqrsSqlServer.DataModel", "CqrsSqlServer.DataModel\CqrsSqlServer.DataModel.csproj", "{A1B9790C-AC65-46C0-8BC5-2C4013F5245D}"
1111
EndProject
12+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CqrsSqlServer.Frontend", "CqrsSqlServer.Frontend\CqrsSqlServer.Frontend.csproj", "{D291AA52-B8AA-4A8C-A5F2-9323259DAACF}"
13+
EndProject
1214
Global
1315
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1416
Debug|Any CPU = Debug|Any CPU
@@ -30,5 +32,11 @@ Global
3032
{A1B9790C-AC65-46C0-8BC5-2C4013F5245D}.Debug|Any CPU.Build.0 = Debug|Any CPU
3133
{A1B9790C-AC65-46C0-8BC5-2C4013F5245D}.Release|Any CPU.ActiveCfg = Release|Any CPU
3234
{A1B9790C-AC65-46C0-8BC5-2C4013F5245D}.Release|Any CPU.Build.0 = Release|Any CPU
35+
{D291AA52-B8AA-4A8C-A5F2-9323259DAACF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
36+
{D291AA52-B8AA-4A8C-A5F2-9323259DAACF}.Debug|Any CPU.Build.0 = Debug|Any CPU
37+
{D291AA52-B8AA-4A8C-A5F2-9323259DAACF}.Release|Any CPU.ActiveCfg = Release|Any CPU
38+
{D291AA52-B8AA-4A8C-A5F2-9323259DAACF}.Release|Any CPU.Build.0 = Release|Any CPU
39+
EndGlobalSection
40+
GlobalSection(NestedProjects) = preSolution
3341
EndGlobalSection
3442
EndGlobal

0 commit comments

Comments
 (0)