using DeepDrftManager.Services; using DeepDrftModels.DTOs; using DeepDrftModels.Enums; using Microsoft.AspNetCore.Components; using MudBlazor; namespace DeepDrftManager.Components.Pages.Tracks; /// /// Shared fetch + state logic for the single-track medium browsers (Sessions, Mixes). Analogous to the /// public-site MediumBrowseBase: subclasses supply the , the noun used in /// error text, and a per-row projection from to their own row model; this base /// owns the loading flag, the row list, the initial load, and the cover-thumbnail URL helper. The shared /// table structure lives in CmsMediumTable; subclasses render it and fill only the action column. /// /// The subclass's row model wrapping a . public abstract class CmsMediumBrowserBase : ComponentBase { [Inject] public required ICmsReleaseService CmsReleaseService { get; set; } [Inject] public required ISnackbar Snackbar { get; set; } /// The medium this browser lists. Subclass-supplied constant. protected abstract ReleaseMedium Medium { get; } /// Plural noun for this medium used in error text (e.g. "sessions", "mixes"). protected abstract string MediumNoun { get; } /// Projects a fetched release into the subclass's row model. protected abstract TRow ToRow(ReleaseDto release); protected List Rows { get; private set; } = new(); protected bool Loading { get; private set; } = true; protected override async Task OnInitializedAsync() => await LoadAsync(); private async Task LoadAsync() { Loading = true; // Single-track releases; a single generous page covers the CMS catalogue (same small-catalogue // assumption the album browser makes). var result = await CmsReleaseService.GetPagedAsync( Medium, page: 1, pageSize: 100, sortColumn: "Title", sortDescending: false); if (result.Success && result.Value is not null) { Rows = result.Value.Items.Select(ToRow).ToList(); } else { var error = result.Messages.FirstOrDefault()?.Message ?? "Unknown error"; Snackbar.Add($"Failed to load {MediumNoun}: {error}", Severity.Error); Rows = new List(); } Loading = false; } // Relative path — resolves against the Manager's own origin, proxied by ImageProxyController. protected static string ThumbUrl(string entryKey) => $"/api/image/{Uri.EscapeDataString(entryKey)}"; }