Skip to content

Commit ba7d0df

Browse files
authored
Responsive pagination, music album, edit form (#459)
* Improve pagination * Update reusable component for packaging * Add music albums * Add music album, replace inline edit with popup * Update NuGet package Fix AutoMapper vulnerability .NET 10.0.5 * Update pkg ref
1 parent 9014fb6 commit ba7d0df

42 files changed

Lines changed: 763 additions & 175 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/pkg.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ jobs:
2828
permissions:
2929
id-token: write
3030
contents: read
31-
uses: devpro/github-workflow-parts/.github/workflows/reusable-container-publication.yml@62dbf6e833e49230ab34ef3c44093ebb727a095f
31+
uses: devpro/github-workflow-parts/.github/workflows/reusable-container-publication.yml@4f3152777635eb3bcf1ee21db103d70f790ff1cb
3232
with:
3333
create-latest: ${{ github.ref_name == 'main' }}
3434
image-definition: ${{ matrix.image-definition }}

Directory.Packages.props

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,25 @@
44
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
55
</PropertyGroup>
66
<ItemGroup>
7-
<PackageVersion Include="AutoMapper" Version="16.1.0" />
7+
<PackageVersion Include="AutoMapper" Version="16.1.1" />
88
<PackageVersion Include="AwesomeAssertions" Version="9.4.0" />
99
<PackageVersion Include="BCrypt.Net-Next" Version="4.1.0" />
1010
<PackageVersion Include="Bogus" Version="35.6.5" />
1111
<PackageVersion Include="FirebaseAdmin" Version="3.4.0" />
12-
<PackageVersion Include="Microsoft.AspNetCore.Authentication.Google" Version="10.0.3" />
13-
<PackageVersion Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="10.0.3" />
14-
<PackageVersion Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="10.0.3" />
15-
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="10.0.3" />
16-
<PackageVersion Include="Microsoft.AspNetCore.OpenApi" Version="10.0.3" />
17-
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="10.0.3" />
18-
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.3" />
12+
<PackageVersion Include="Microsoft.AspNetCore.Authentication.Google" Version="10.0.5" />
13+
<PackageVersion Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="10.0.5" />
14+
<PackageVersion Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="10.0.5" />
15+
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="10.0.5" />
16+
<PackageVersion Include="Microsoft.AspNetCore.OpenApi" Version="10.0.5" />
17+
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="10.0.5" />
18+
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.5" />
1919
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.3.0" />
2020
<PackageVersion Include="Microsoft.Testing.Extensions.CodeCoverage" Version="18.5.2" />
2121
<PackageVersion Include="Microsoft.Testing.Extensions.TrxReport" Version="2.1.0" />
2222
<PackageVersion Include="MongoDB.Bson" Version="3.7.0" />
2323
<PackageVersion Include="MongoDB.Driver" Version="3.7.0" />
2424
<PackageVersion Include="Moq" Version="4.20.72" />
25-
<PackageVersion Include="Scalar.AspNetCore" Version="2.13.1" />
25+
<PackageVersion Include="Scalar.AspNetCore" Version="2.13.8" />
2626
<PackageVersion Include="SharpCompress" Version="0.44.5" />
2727
<PackageVersion Include="System.CodeDom" Version="10.0.3" />
2828
<PackageVersion Include="System.Management" Version="10.0.3" />

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=devpro_keeptrack&metric=alert_status)](https://sonarcloud.io/dashboard?id=devpro_keeptrack)
66
[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=devpro_keeptrack&metric=coverage)](https://sonarcloud.io/dashboard?id=devpro_keeptrack)
77
[![Docker Image Version](https://img.shields.io/docker/v/devprofr/keeptrack-blazorapp?label=Image&logo=docker)](https://hub.docker.com/r/devprofr/keeptrack-blazorapp)
8+
89
[![FOSSA Status](https://app.fossa.com/api/projects/custom%2B60068%2Fgithub.com%2Fdevpro%2Fkeeptrack.svg?type=shield&issueType=license)](https://app.fossa.com/projects/custom%2B60068%2Fgithub.com%2Fdevpro%2Fkeeptrack?ref=badge_shield&issueType=license)
910
[![FOSSA Status](https://app.fossa.com/api/projects/custom%2B60068%2Fgithub.com%2Fdevpro%2Fkeeptrack.svg?type=shield&issueType=security)](https://app.fossa.com/projects/custom%2B60068%2Fgithub.com%2Fdevpro%2Fkeeptrack?ref=badge_shield&issueType=security)
1011

src/BlazorApp/Components/Inventory/Clients/MoviesApiClient.cs renamed to src/BlazorApp/Components/Inventory/Clients/MovieApiClient.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace Keeptrack.BlazorApp.Components.Inventory.Clients;
44

5-
public sealed class MoviesApiClient(HttpClient http)
5+
public sealed class MovieApiClient(HttpClient http)
66
: InventoryApiClientBase<MovieDto>(http)
77
{
88
protected override string ApiResourceName => "/api/movies";
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
using Keeptrack.WebApi.Contracts.Dto;
2+
3+
namespace Keeptrack.BlazorApp.Components.Inventory.Clients;
4+
5+
public sealed class MusicAlbumApiClient(HttpClient http)
6+
: InventoryApiClientBase<MusicAlbumDto>(http)
7+
{
8+
protected override string ApiResourceName => "/api/movies";
9+
}

src/BlazorApp/Components/Inventory/Pages/Books.razor

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,24 +31,51 @@
3131
<th>Title</th>
3232
<th>Author</th>
3333
<th>Series</th>
34+
<th>Rating</th>
3435
<th>Finished at</th>
3536
</HeaderTemplate>
3637
<RowTemplate Context="book">
3738
<td>@book.Title</td>
3839
<td>@book.Author</td>
3940
<td>@book.Series</td>
40-
<td>@book.FinishedAt?.ToString("yyyy-MM-dd")</td>
41+
<td><span class="kt-stars"><StarRating Rating="book.Rating" /></span></td>
42+
<td>@book.FirstReadAt?.ToString("yyyy-MM-dd")</td>
4143
</RowTemplate>
4244
<FormTemplate Context="book">
4345
<input class="form-control" placeholder="Title" @bind="book.Title" />
4446
<input class="form-control" placeholder="Author" @bind="book.Author" />
4547
<input class="form-control" placeholder="Series" @bind="book.Series" />
46-
<input class="form-control" type="date" placeholder="Finished at" @bind="book.FinishedAt" @bind:format="yyyy-MM-dd" />
48+
<input class="form-control" @bind="book.Rating" type="number" min="0" max="5" step="0.1" />
49+
<input class="form-control" placeholder="Finished at" @bind="book.FirstReadAt" @bind:format="yyyy-MM-dd" type="date" />
4750
</FormTemplate>
48-
<InlineEditTemplate Context="book">
49-
<td><input class="form-control form-control-sm" @bind="book.Title" /></td>
50-
<td><input class="form-control form-control-sm" @bind="book.Author" /></td>
51-
<td><input class="form-control form-control-sm" @bind="book.Series" /></td>
52-
<td><input class="form-control" type="date" @bind="book.FinishedAt" @bind:format="yyyy-MM-dd" /></td>
53-
</InlineEditTemplate>
51+
<EditModalTemplate Context="book">
52+
<div class="col-12">
53+
<label class="form-label">Title</label>
54+
<input class="form-control" @bind="book.Title" />
55+
</div>
56+
<div class="col-md-6">
57+
<label class="form-label">Author</label>
58+
<input class="form-control" @bind="book.Author" />
59+
</div>
60+
<div class="col-md-6">
61+
<label class="form-label">Series</label>
62+
<input class="form-control" @bind="book.Series" />
63+
</div>
64+
<div class="col-md-6">
65+
<label class="form-label">Genre</label>
66+
<input class="form-control" @bind="book.Genre" />
67+
</div>
68+
<div class="col-md-6">
69+
<label class="form-label">Rating</label>
70+
<input class="form-control" @bind="book.Rating" type="number" min="0" max="5" step="0.1" />
71+
</div>
72+
<div class="col-md-6">
73+
<label class="form-label">Notes</label>
74+
<textarea class="form-control" @bind="book.Notes" rows="4"></textarea>
75+
</div>
76+
<div class="col-md-6">
77+
<label class="form-label">First read at</label>
78+
<input class="form-control" type="date" @bind="book.FirstReadAt" @bind:format="yyyy-MM-dd" />
79+
</div>
80+
</EditModalTemplate>
5481
</InventoryList>

src/BlazorApp/Components/Inventory/Pages/Books.razor.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@ public partial class Books : InventoryPageBase<BookDto>
1414
Id = item.Id,
1515
Title = item.Title,
1616
Author = item.Author,
17-
FinishedAt = item.FinishedAt,
18-
Series = item.Series
17+
Series = item.Series,
18+
Genre = item.Genre,
19+
Rating = item.Rating,
20+
Notes = item.Notes,
21+
FirstReadAt = item.FirstReadAt
1922
};
2023
}

src/BlazorApp/Components/Inventory/Pages/Movies.razor

Lines changed: 33 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -30,54 +30,46 @@
3030
<HeaderTemplate>
3131
<th>Title</th>
3232
<th>Year</th>
33-
<th>Genre</th>
3433
<th>Rating</th>
35-
<th>Notes</th>
34+
<td>First seen</td>
3635
</HeaderTemplate>
3736
<RowTemplate Context="movie">
3837
<td style="font-weight:500">@movie.Title</td>
39-
<td style="color:var(--kt-text-muted)">@(movie.Year > 0 ? movie.Year : "")</td>
40-
<td style="color:var(--kt-text-muted)">@(string.IsNullOrEmpty(movie.Genre) ? "" : movie.Genre)</td>
41-
<td>
42-
@if (movie.Rating > 0)
43-
{
44-
<span class="kt-stars">
45-
@(new string('★', movie.Rating ?? 0))<span class="empty">@(new string('★', 5 - (movie.Rating ?? 0)))</span>
46-
</span>
47-
}
48-
else
49-
{
50-
<span style="color:var(--kt-text-subtle)">—</span>
51-
}
52-
</td>
53-
<td style="color:var(--kt-text-muted); font-size:0.85rem">@(string.IsNullOrEmpty(movie.Notes) ? "" : movie.Notes)</td>
38+
<td style="color:var(--kt-text-muted)">@(movie.Year > 0 ? movie.Year : "")</td>
39+
<td><span class="kt-stars"><StarRating Rating="movie.Rating" /></span></td>
40+
<td>@movie.FirstSeenAt?.ToString("yyyy-MM-dd")</td>
5441
</RowTemplate>
5542
<FormTemplate Context="movie">
5643
<input class="form-control" placeholder="Title" @bind="movie.Title"/>
57-
<input class="form-control" placeholder="Year" type="number" @bind="movie.Year"/>
44+
<input class="form-control" @bind="movie.Year" type="number" min="1970" max="2100" />
5845
<input class="form-control" placeholder="Genre" @bind="movie.Genre"/>
59-
<select class="form-select" @bind="movie.Rating">
60-
<option value="0">—</option>
61-
@for (var i = 1; i <= 5; i++)
62-
{
63-
<option value="@i">@(new string('★', i))</option>
64-
}
65-
</select>
66-
<input class="form-control" placeholder="Notes" @bind="movie.Notes"/>
46+
<input class="form-control" placeholder="Rating" @bind="movie.Rating" type="number" />
47+
<textarea class="form-control" rows="4" @bind="movie.Notes"></textarea>
6748
</FormTemplate>
68-
<InlineEditTemplate Context="movie">
69-
<td><input class="form-control form-control-sm" @bind="movie.Title"/></td>
70-
<td><input class="form-control form-control-sm" type="number" @bind="movie.Year" style="width:80px"/></td>
71-
<td><input class="form-control form-control-sm" @bind="movie.Genre"/></td>
72-
<td>
73-
<select class="form-select form-select-sm" @bind="movie.Rating" style="width:80px">
74-
<option value="0">—</option>
75-
@for (var i = 1; i <= 5; i++)
76-
{
77-
<option value="@i">@(new string('★', i))</option>
78-
}
79-
</select>
80-
</td>
81-
<td><input class="form-control form-control-sm" @bind="movie.Notes"/></td>
82-
</InlineEditTemplate>
49+
<EditModalTemplate Context="movie">
50+
<div class="col-12">
51+
<label class="form-label">Title</label>
52+
<input class="form-control" @bind="movie.Title" />
53+
</div>
54+
<div class="col-md-6">
55+
<label class="form-label">Year</label>
56+
<input class="form-control" @bind="movie.Year" type="number" min="1970" max="2100" />
57+
</div>
58+
<div class="col-md-6">
59+
<label class="form-label">Genre</label>
60+
<input class="form-control" @bind="movie.Genre" />
61+
</div>
62+
<div class="col-md-6">
63+
<label class="form-label">Rating</label>
64+
<input class="form-control" @bind="movie.Rating" type="number" />
65+
</div>
66+
<div class="col-md-6">
67+
<label class="form-label">Notes</label>
68+
<textarea class="form-control" rows="4" @bind="movie.Notes"></textarea>
69+
</div>
70+
<div class="col-md-6">
71+
<label class="form-label">First seen at</label>
72+
<input class="form-control" type="date" @bind="movie.FirstSeenAt" @bind:format="yyyy-MM-dd" />
73+
</div>
74+
</EditModalTemplate>
8375
</InventoryList>

src/BlazorApp/Components/Inventory/Pages/Movies.razor.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ namespace Keeptrack.BlazorApp.Components.Inventory.Pages;
55

66
public partial class Movies : InventoryPageBase<MovieDto>
77
{
8-
[Inject] private MoviesApiClient MovieApi { get; set; } = null!;
8+
[Inject] private MovieApiClient MovieApi { get; set; } = null!;
99

1010
protected override InventoryApiClientBase<MovieDto> Api => MovieApi;
1111

@@ -16,6 +16,9 @@ public partial class Movies : InventoryPageBase<MovieDto>
1616
Year = item.Year,
1717
Genre = item.Genre,
1818
Rating = item.Rating,
19-
Notes = item.Notes
19+
Notes = item.Notes,
20+
FirstSeenAt = item.FirstSeenAt,
21+
AllocineId = item.AllocineId,
22+
ImdbPageId = item.ImdbPageId
2023
};
2124
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
@page "/music-albums"
2+
@inherits InventoryPageBase<MusicAlbumDto>
3+
@rendermode InteractiveServer
4+
@attribute [Authorize]
5+
6+
<InventoryList TDto="MusicAlbumDto"
7+
Title="Music Albums"
8+
Items="@_items"
9+
Loading="@_loading"
10+
Error="@_error"
11+
Search="@_search"
12+
Page="@_page"
13+
TotalPages="@TotalPages"
14+
TotalCount="@_totalCount"
15+
ShowForm="@_showForm"
16+
EditingInline="@_editingInline"
17+
Form="@_form"
18+
InlineForm="@_inlineForm"
19+
OnSearchKeyUp="@OnSearchKeyUp"
20+
OnClearSearch="@ClearSearch"
21+
OnGoToPage="@GoToPage"
22+
OnShowAddForm="@ShowAddForm"
23+
OnCancelForm="@CancelForm"
24+
OnSave="@SaveAsync"
25+
OnStartInlineEdit="@StartInlineEdit"
26+
OnCancelInline="@CancelInline"
27+
OnSaveInline="@SaveInlineAsync"
28+
OnDelete="@DeleteAsync"
29+
OnSearchChanged="@OnSearchChanged">
30+
<HeaderTemplate>
31+
<th>Title</th>
32+
<th>Artist</th>
33+
<th>Rating</th>
34+
</HeaderTemplate>
35+
<RowTemplate Context="album">
36+
<td>@album.Title</td>
37+
<td>@album.Artist</td>
38+
<td><span class="kt-stars"><StarRating Rating="album.Rating" /></span></td>
39+
</RowTemplate>
40+
<FormTemplate Context="album">
41+
<input class="form-control" placeholder="Title" @bind="album.Title" />
42+
<input class="form-control" placeholder="Author" @bind="album.Artist" />
43+
<input class="form-control" placeholder="Rating" @bind="album.Rating" type="number" />
44+
</FormTemplate>
45+
<EditModalTemplate Context="album">
46+
<div class="col-12">
47+
<label class="form-label">Title</label>
48+
<input class="form-control" @bind="album.Title" />
49+
</div>
50+
<div class="col-md-6">
51+
<label class="form-label">Artist</label>
52+
<input class="form-control" @bind="album.Artist" />
53+
</div>
54+
<div class="col-md-6">
55+
<label class="form-label">Year</label>
56+
<input class="form-control" @bind="album.Year" type="number" />
57+
</div>
58+
<div class="col-md-6">
59+
<label class="form-label">Genre</label>
60+
<input class="form-control" @bind="album.Genre" />
61+
</div>
62+
<div class="col-md-6">
63+
<label class="form-label">Rating</label>
64+
<input class="form-control" @bind="album.Rating" type="number" />
65+
</div>
66+
</EditModalTemplate>
67+
</InventoryList>

0 commit comments

Comments
 (0)