Track Gallery front end
- For now uses a table but will replace with graphical media cards
This commit is contained in:
@@ -0,0 +1,46 @@
|
|||||||
|
using DeepDrftModels.Entities;
|
||||||
|
using DeepDrftModels.Models;
|
||||||
|
using NetBlocks.Models;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Web;
|
||||||
|
|
||||||
|
namespace DeepDrftWeb.Client.Clients;
|
||||||
|
|
||||||
|
public class TrackClient : ApiClient<ClientConfig>
|
||||||
|
{
|
||||||
|
public TrackClient(ClientConfig config) : base(config) { }
|
||||||
|
|
||||||
|
public async Task<ApiResult<PagedResult<TrackEntity>>> GetPage(
|
||||||
|
int pageNumber,
|
||||||
|
int pageSize,
|
||||||
|
string? sortColumn = null,
|
||||||
|
bool sortDescending = false)
|
||||||
|
{
|
||||||
|
var uriBuilder = new UriBuilder(http.BaseAddress!)
|
||||||
|
{
|
||||||
|
Path = "api/track/page"
|
||||||
|
};
|
||||||
|
|
||||||
|
var query = HttpUtility.ParseQueryString(string.Empty);
|
||||||
|
query["pageNumber"] = pageNumber.ToString();
|
||||||
|
query["pageSize"] = pageSize.ToString();
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(sortColumn))
|
||||||
|
query["sortColumn"] = sortColumn;
|
||||||
|
|
||||||
|
if (sortDescending)
|
||||||
|
query["sortDescending"] = "true";
|
||||||
|
|
||||||
|
uriBuilder.Query = query.ToString();
|
||||||
|
|
||||||
|
var response = await http.GetAsync(uriBuilder.Uri);
|
||||||
|
var json = await response.Content.ReadAsStringAsync();
|
||||||
|
|
||||||
|
var dto = JsonSerializer.Deserialize<ApiResultDto<PagedResult<TrackEntity>>>(json, new JsonSerializerOptions
|
||||||
|
{
|
||||||
|
PropertyNameCaseInsensitive = true
|
||||||
|
});
|
||||||
|
|
||||||
|
return dto?.From() ?? ApiResult<PagedResult<TrackEntity>>.CreateFailResult("Failed to deserialize response");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,10 +1,7 @@
|
|||||||
|
|
||||||
<MudNavMenu>
|
<MudNavMenu>
|
||||||
<MudNavLink Href="" Match="NavLinkMatch.All" Icon="@Icons.Material.Filled.Home">Home</MudNavLink>
|
<MudNavLink Href="" Match="NavLinkMatch.All" Icon="@Icons.Material.Filled.Home">Home</MudNavLink>
|
||||||
<MudNavLink Href="counter" Match="NavLinkMatch.Prefix" Icon="@Icons.Material.Filled.Add">Counter</MudNavLink>
|
<MudNavLink Href="/tracks" Match="NavLinkMatch.Prefix" Icon="@Icons.Material.Filled.BrowseGallery">Track Gallery</MudNavLink>
|
||||||
|
|
||||||
<MudNavLink Href="weather" Match="NavLinkMatch.Prefix" Icon="@Icons.Material.Filled.List">Weather</MudNavLink>
|
|
||||||
|
|
||||||
</MudNavMenu>
|
</MudNavMenu>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,59 +1,4 @@
|
|||||||
@page "/"
|
@page "/"
|
||||||
|
|
||||||
<PageTitle>Home</PageTitle>
|
<PageTitle>Deep Drft Home</PageTitle>
|
||||||
|
|
||||||
<MudText Typo="Typo.h3" GutterBottom="true">Hello, world!</MudText>
|
|
||||||
<MudText Class="mb-8">Welcome to your new app, powered by MudBlazor and the .NET 9 Template!</MudText>
|
|
||||||
|
|
||||||
<MudAlert Severity="Severity.Normal" ContentAlignment="HorizontalAlignment.Start">
|
|
||||||
You can find documentation and examples on our website here:
|
|
||||||
<MudLink Href="https://mudblazor.com" Target="_blank" Typo="Typo.body2" Color="Color.Primary">
|
|
||||||
<b>www.mudblazor.com</b>
|
|
||||||
</MudLink>
|
|
||||||
</MudAlert>
|
|
||||||
|
|
||||||
<br />
|
|
||||||
<MudText Typo="Typo.h5" GutterBottom="true">Interactivity in this Template</MudText>
|
|
||||||
<br />
|
|
||||||
<MudText Typo="Typo.body2">
|
|
||||||
When you opt for the "Global" Interactivity Location, <br />
|
|
||||||
the render modes are defined in App.razor and consequently apply to all child components.<br />
|
|
||||||
In this case, providers are globally set in the MainLayout.<br />
|
|
||||||
<br />
|
|
||||||
On the other hand, if you choose the "Per page/component" Interactivity Location,<br />
|
|
||||||
it is necessary to include the <br />
|
|
||||||
<br />
|
|
||||||
<MudPopoverProvider /> <br />
|
|
||||||
<MudDialogProvider /> <br />
|
|
||||||
<MudSnackbarProvider /> <br />
|
|
||||||
<br />
|
|
||||||
components on every interactive page.<br />
|
|
||||||
<br />
|
|
||||||
If a render mode is not specified for a page, it defaults to Server-Side Rendering (SSR),<br />
|
|
||||||
similar to this page. While MudBlazor allows pages to be rendered in SSR,<br />
|
|
||||||
please note that interactive features, such as buttons and dropdown menus, will not be functional.
|
|
||||||
</MudText>
|
|
||||||
|
|
||||||
<br />
|
|
||||||
<MudText Typo="Typo.h5" GutterBottom="true">What's New in Blazor with the Release of .NET 9</MudText>
|
|
||||||
<br />
|
|
||||||
|
|
||||||
<MudText Typo="Typo.h6" GutterBottom="true">Prerendering</MudText>
|
|
||||||
<MudText Typo="Typo.body2" GutterBottom="true">
|
|
||||||
If you're exploring the features of .NET 9 Blazor,<br /> you might be pleasantly surprised to learn that each page is prerendered on the server,<br /> regardless of the selected render mode.<br /><br />
|
|
||||||
This means that you'll need to inject all necessary services on the server,<br /> even when opting for the wasm (WebAssembly) render mode.<br /><br />
|
|
||||||
This prerendering functionality is crucial to ensuring that WebAssembly mode feels fast and responsive,<br /> especially when it comes to initial page load times.<br /><br />
|
|
||||||
For more information on how to detect prerendering and leverage the RenderContext, you can refer to the following link:
|
|
||||||
<MudLink Href="https://github.com/dotnet/aspnetcore/issues/51468#issuecomment-1783568121" Target="_blank" Typo="Typo.body2" Color="Color.Primary">
|
|
||||||
More details
|
|
||||||
</MudLink>
|
|
||||||
</MudText>
|
|
||||||
|
|
||||||
<br />
|
|
||||||
<MudText Typo="Typo.h6" GutterBottom="true">InteractiveAuto</MudText>
|
|
||||||
<MudText Typo="Typo.body2">
|
|
||||||
A discussion on how to achieve this can be found here:
|
|
||||||
<MudLink Href="https://github.com/dotnet/aspnetcore/issues/51468#issue-1950424116" Target="_blank" Typo="Typo.body2" Color="Color.Primary">
|
|
||||||
More details
|
|
||||||
</MudLink>
|
|
||||||
</MudText>
|
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
@page "/tracks"
|
||||||
|
@using DeepDrftModels.DTOs
|
||||||
|
@using DeepDrftModels.Entities
|
||||||
|
|
||||||
|
<h3>Track Gallery</h3>
|
||||||
|
|
||||||
|
<MudContainer>
|
||||||
|
|
||||||
|
@if (ViewModel.Page != null)
|
||||||
|
{
|
||||||
|
<MudTable T="TrackEntity" Items="@ViewModel.Page.Items" Hover="true" Breakpoint="Breakpoint.Sm">
|
||||||
|
<HeaderContent>
|
||||||
|
<MudTh>Name</MudTh>
|
||||||
|
<MudTh>Artist</MudTh>
|
||||||
|
<MudTh>Album</MudTh>
|
||||||
|
<MudTh>Genre</MudTh>
|
||||||
|
<MudTh>Released</MudTh>
|
||||||
|
<MudTh>Actions</MudTh>
|
||||||
|
</HeaderContent>
|
||||||
|
<RowTemplate>
|
||||||
|
<MudTd DataLabel="Name">@context.TrackName</MudTd>
|
||||||
|
<MudTd DataLabel="Artist">@context.Artist</MudTd>
|
||||||
|
<MudTd DataLabel="Album">@context.Album</MudTd>
|
||||||
|
<MudTd DataLabel="Genre">@context.Genre</MudTd>
|
||||||
|
<MudTd DataLabel="Released">@context.ReleaseDate</MudTd>
|
||||||
|
<MudTd DataLabel="Actions">
|
||||||
|
<MudButton Variant="Variant.Text" Color="Color.Primary">View</MudButton>
|
||||||
|
</MudTd>
|
||||||
|
</RowTemplate>
|
||||||
|
</MudTable>
|
||||||
|
|
||||||
|
<MudPagination Count="@ViewModel.Page.TotalPages" Selected="@ViewModel.Page.Page" SelectedChanged="i => SetPage(i)" BoundaryCount="2" MiddleCount="3"/>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<MudSkeleton Height="650px" Class="pa-2 ma-2"/>
|
||||||
|
<MudSkeleton Height="80px"/>
|
||||||
|
<MudSpacer />
|
||||||
|
}
|
||||||
|
</MudContainer>
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
using DeepDrftModels.Entities;
|
||||||
|
using DeepDrftModels.Models;
|
||||||
|
using DeepDrftWeb.Client.ViewModels;
|
||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
|
||||||
|
namespace DeepDrftWeb.Client.Pages;
|
||||||
|
|
||||||
|
public partial class TrackGallery : ComponentBase
|
||||||
|
{
|
||||||
|
[Inject]
|
||||||
|
public required TrackGalleryViewModel ViewModel { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
await SetPage(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task SetPage(int newPage)
|
||||||
|
{
|
||||||
|
var result = await ViewModel.TrackClient.GetPage(newPage, ViewModel.PageSize, ViewModel.SortBy, ViewModel.IsDescending);
|
||||||
|
|
||||||
|
if (result is { Success: true, Value: PagedResult<TrackEntity> pageResult })
|
||||||
|
{
|
||||||
|
ViewModel.Page = pageResult;
|
||||||
|
ViewModel.PageSize = pageResult.PageSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using DeepDrftWeb.Client;
|
||||||
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
||||||
using MudBlazor.Services;
|
using MudBlazor.Services;
|
||||||
|
|
||||||
@@ -5,4 +6,6 @@ var builder = WebAssemblyHostBuilder.CreateDefault(args);
|
|||||||
|
|
||||||
builder.Services.AddMudServices();
|
builder.Services.AddMudServices();
|
||||||
|
|
||||||
|
Startup.ConfigureDomainServices(builder.Services, builder.HostEnvironment.BaseAddress);
|
||||||
|
|
||||||
await builder.Build().RunAsync();
|
await builder.Build().RunAsync();
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
using DeepDrftWeb.Client.Clients;
|
||||||
|
using DeepDrftWeb.Client.ViewModels;
|
||||||
|
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
||||||
|
using NetBlocks.Models;
|
||||||
|
|
||||||
|
namespace DeepDrftWeb.Client;
|
||||||
|
|
||||||
|
public static class Startup
|
||||||
|
{
|
||||||
|
public static void ConfigureDomainServices(IServiceCollection services, string baseAddress)
|
||||||
|
{
|
||||||
|
// HTTP Client for Server API
|
||||||
|
services.AddScoped(_ => new HttpClient { BaseAddress = new Uri(baseAddress) });
|
||||||
|
|
||||||
|
// Track Client
|
||||||
|
services.AddSingleton(new ClientConfig(baseAddress));
|
||||||
|
services.AddScoped<TrackClient>();
|
||||||
|
services.AddScoped<TrackGalleryViewModel>();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
using DeepDrftModels.Entities;
|
||||||
|
using DeepDrftModels.Models;
|
||||||
|
using DeepDrftWeb.Client.Clients;
|
||||||
|
|
||||||
|
namespace DeepDrftWeb.Client.ViewModels;
|
||||||
|
|
||||||
|
public class TrackGalleryViewModel
|
||||||
|
{
|
||||||
|
public TrackClient TrackClient { get; }
|
||||||
|
|
||||||
|
// private int _pageNumber = 1;
|
||||||
|
public int PageNumber { get; set; } = 1;
|
||||||
|
|
||||||
|
public int PageSize
|
||||||
|
{
|
||||||
|
get => Page?.PageSize ?? 15;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (Page == null) throw new Exception();
|
||||||
|
if (value != Page.PageSize)
|
||||||
|
{
|
||||||
|
Page.PageSize = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public string SortBy { get; set; } = string.Empty;
|
||||||
|
public bool IsDescending { get; set; } = false;
|
||||||
|
public PagedResult<TrackEntity>? Page { get; set; } = null;
|
||||||
|
|
||||||
|
public TrackGalleryViewModel(TrackClient trackClient)
|
||||||
|
{
|
||||||
|
TrackClient = trackClient;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,6 +11,8 @@ builder.Services.AddMudServices();
|
|||||||
|
|
||||||
Startup.ConfigureDomainServices(builder);
|
Startup.ConfigureDomainServices(builder);
|
||||||
|
|
||||||
|
var hostUrl = builder.Configuration.GetValue<string>("ASPNETCORE_URLS")?.Split(';').First() ?? throw new Exception("ASPNETCORE_URLS undefined");
|
||||||
|
DeepDrftWeb.Client.Startup.ConfigureDomainServices(builder.Services, hostUrl);
|
||||||
|
|
||||||
builder.Services.AddControllers();
|
builder.Services.AddControllers();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user