@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. *@
@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 _releases = Array.Empty();
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();
var error = result.Messages.FirstOrDefault()?.Message ?? "Unknown error";
Snackbar.Add($"Failed to load releases: {error}", Severity.Error);
}
_loading = false;
StateHasChanged();
}
}