Files
deepdrft/DeepDrftManager/Components/Pages/Tracks/CmsAllReleasesGrid.razor
T
daniel-c-harvey e78a61c3b1 feat(cms): extract all-releases grid as embeddable ALL-tab component (9.8.B)
CmsAllReleasesGrid self-loads the cross-medium release list so 8.A can host it as the ALL tab with no VM plumbing; TrackList's Albums mode renders it now. Preserves sort/delete/expand/edit and the 8.D Type chip.
2026-06-13 21:26:43 -04:00

56 lines
2.3 KiB
Plaintext

@using DeepDrftManager.Services
@using DeepDrftModels.DTOs
@inject ICmsTrackService CmsTrackService
@inject ISnackbar Snackbar
@* The ALL-tab content (Phase 9 §8.B): the cross-medium all-releases grid (CUTS, SESSIONS, MIXES
together) with per-row edit, delete, expand-tracks, and the 8.D Type chip. Self-contained — owns its
own data load so a host (TrackList today, the 8.A tab strip later) renders it with no parameters and
no VM plumbing. Re-loads on first render and re-fetches after a row mutation so the list stays in
sync with the catalogue. *@
<CmsAlbumBrowser Releases="_releases"
IsLoading="_loading"
OnReleasesChanged="OnGridReleasesChanged" />
@code {
// Fires after a row mutation (delete) so a host can invalidate sibling caches derived from the same
// catalogue — e.g. TrackList's genre cache. The grid refreshes its own list regardless; this is a
// notification, not the data source. Optional: an embed that has no sibling state leaves it unset.
[Parameter] public EventCallback OnReleasesChanged { get; set; }
private IReadOnlyList<ReleaseDto> _releases = Array.Empty<ReleaseDto>();
private bool _loading = true;
protected override Task OnInitializedAsync() => ReloadAsync();
private async Task OnGridReleasesChanged()
{
await ReloadAsync();
await OnReleasesChanged.InvokeAsync();
}
// Single load path: the initial fetch and the post-mutation refresh both run through here. After a
// delete CmsAlbumBrowser has already dropped the row from its own projection, so this re-fetch
// reconciles the authoritative list (track counts, orphaned-release cleanup) without a stale cache.
private async Task ReloadAsync()
{
_loading = true;
StateHasChanged();
var result = await CmsTrackService.GetReleasesAsync();
if (result.Success && result.Value is not null)
{
_releases = result.Value;
}
else
{
_releases = Array.Empty<ReleaseDto>();
var error = result.Messages.FirstOrDefault()?.Message ?? "Unknown error";
Snackbar.Add($"Failed to load releases: {error}", Severity.Error);
}
_loading = false;
StateHasChanged();
}
}