feat(cms): retire legacy single-track forms; route single-track edit into BatchEdit (8.M)
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
@page "/tracks/album/{AlbumName}/edit"
|
||||
@page "/tracks/{TrackId:long}/edit"
|
||||
@using System.Security.Claims
|
||||
@using DeepDrftManager.Services
|
||||
@using DeepDrftModels.DTOs
|
||||
@@ -111,8 +112,15 @@
|
||||
// 1 GB ceiling matches DeepDrftAPI's per-request limit on api/track/upload.
|
||||
private const long MaxUploadBytes = 1_073_741_824L;
|
||||
|
||||
// Release-title addressing (Album-mode batch Edit): loads the whole release by title.
|
||||
[Parameter] public string AlbumName { get; set; } = string.Empty;
|
||||
|
||||
// Track-id addressing (Track-mode per-row Edit, §8.M): loads the addressed track's parent
|
||||
// release and pre-selects that track's row, so editing a single Cut track lands the admin on
|
||||
// the track they clicked rather than on the release with no row context. Null for the
|
||||
// release-title route. The two routes are mutually exclusive — only one segment binds.
|
||||
[Parameter] public long? TrackId { get; set; }
|
||||
|
||||
private List<BatchRowModel> _tracks = new();
|
||||
private int _selectedIndex = -1;
|
||||
private bool _loading = true;
|
||||
@@ -154,12 +162,35 @@
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
// Track-addressed entry (§8.M): resolve the addressed track to its parent release title,
|
||||
// then fall through to the shared release-load path below. The clicked track's id is held
|
||||
// for row pre-selection once the list is built.
|
||||
var albumName = AlbumName;
|
||||
if (TrackId is { } trackId)
|
||||
{
|
||||
var trackResult = await CmsTrackService.GetByIdAsync(trackId);
|
||||
if (!trackResult.Success || trackResult.Value is not { } track)
|
||||
{
|
||||
_loadError = trackResult.Messages.FirstOrDefault()?.Message ?? "Track not found.";
|
||||
_loading = false;
|
||||
return;
|
||||
}
|
||||
|
||||
albumName = track.Release?.Title;
|
||||
if (string.IsNullOrEmpty(albumName))
|
||||
{
|
||||
_loadError = "This track has no parent release to edit.";
|
||||
_loading = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// A single page of 100 covers the full release (albums are small — same assumption as
|
||||
// CmsAlbumBrowser). Sorted by track number so list order matches the saved ordinals.
|
||||
var result = await CmsTrackService.GetPagedAsync(
|
||||
page: 1, pageSize: 100,
|
||||
sortColumn: "TrackNumber", sortDescending: false,
|
||||
album: AlbumName);
|
||||
album: albumName);
|
||||
|
||||
if (!result.Success || result.Value is null)
|
||||
{
|
||||
@@ -171,13 +202,13 @@
|
||||
var tracks = result.Value.Items.ToList();
|
||||
if (tracks.Count == 0)
|
||||
{
|
||||
_loadError = $"No tracks found for release '{AlbumName}'.";
|
||||
_loadError = $"No tracks found for release '{albumName}'.";
|
||||
_loading = false;
|
||||
return;
|
||||
}
|
||||
|
||||
var release = tracks[0].Release;
|
||||
_albumName = AlbumName;
|
||||
_albumName = albumName;
|
||||
_artist = release?.Artist ?? string.Empty;
|
||||
_genre = release?.Genre ?? string.Empty;
|
||||
_releaseDate = release?.ReleaseDate?.ToString("yyyy-MM-dd") ?? string.Empty;
|
||||
@@ -203,10 +234,24 @@
|
||||
_tracks.RemoveRange(1, _tracks.Count - 1);
|
||||
}
|
||||
|
||||
_selectedIndex = _tracks.Count > 0 ? 0 : -1;
|
||||
// Track-addressed entry pre-selects the clicked row (§8.M Option 2). For a multi-track Cut
|
||||
// the addressed track may be any ordinal; for single-track media it is always row 0 (the
|
||||
// collapse above leaves one row). Fall back to row 0 if the id is absent or trimmed away.
|
||||
_selectedIndex = ResolveInitialSelection();
|
||||
_loading = false;
|
||||
}
|
||||
|
||||
private int ResolveInitialSelection()
|
||||
{
|
||||
if (_tracks.Count == 0) return -1;
|
||||
if (TrackId is { } trackId)
|
||||
{
|
||||
var addressed = _tracks.FindIndex(t => t.Id == trackId);
|
||||
if (addressed >= 0) return addressed;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private void HandleWavFilesSelected(IReadOnlyList<IBrowserFile> files)
|
||||
{
|
||||
_errorMessage = null;
|
||||
@@ -471,7 +516,7 @@
|
||||
|
||||
if (!linkResult.Success)
|
||||
{
|
||||
// Non-blocking: track persisted; cover can be linked via TrackEdit.
|
||||
// Non-blocking: track persisted; cover can be re-linked by re-editing.
|
||||
Logger.LogWarning("Batch edit: cover link failed for new track '{TrackName}' (id={Id})",
|
||||
row.TrackName, uploadResult.Value.Id);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user