Merge p9-w8-8e-add-track-buttons into dev (8.E: medium-aware Add Track on Release Archive tabs)
This commit is contained in:
@@ -130,6 +130,25 @@
|
|||||||
private ReleaseType _releaseType = ReleaseType.Single;
|
private ReleaseType _releaseType = ReleaseType.Single;
|
||||||
private ReleaseMedium _medium = ReleaseMedium.Cut;
|
private ReleaseMedium _medium = ReleaseMedium.Cut;
|
||||||
|
|
||||||
|
// Optional pre-select from the Add-Track buttons (§8.E): /tracks/upload?medium=session lands the
|
||||||
|
// form already in Session mode. A seed only — the medium selector stays user-changeable after load.
|
||||||
|
// Unrecognised/absent values fall through to the Cut default (same defensive posture as the API's
|
||||||
|
// TrackController.UploadTrack medium parse).
|
||||||
|
[SupplyParameterFromQuery(Name = "medium")] public string? MediumParam { get; set; }
|
||||||
|
|
||||||
|
protected override void OnInitialized()
|
||||||
|
{
|
||||||
|
// Seed the medium from the query param so a pre-selected upload form (e.g. the Sessions tab's
|
||||||
|
// Add Track) lands already showing that medium's conditional fields. Goes through OnMediumChanged
|
||||||
|
// so the single-track collapse runs identically to a user selector change.
|
||||||
|
if (!string.IsNullOrWhiteSpace(MediumParam)
|
||||||
|
&& Enum.TryParse<ReleaseMedium>(MediumParam, ignoreCase: true, out var medium)
|
||||||
|
&& Enum.IsDefined(medium))
|
||||||
|
{
|
||||||
|
OnMediumChanged(medium);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Switching to a single-track medium collapses any multi-track selection to the first row so the
|
// Switching to a single-track medium collapses any multi-track selection to the first row so the
|
||||||
// single-track invariant holds before submit. The predicate reads the same MediumRules cardinality
|
// single-track invariant holds before submit. The predicate reads the same MediumRules cardinality
|
||||||
// declaration the upload service enforces, so the form and the domain cannot drift.
|
// declaration the upload service enforces, so the form and the domain cannot drift.
|
||||||
|
|||||||
@@ -61,7 +61,21 @@
|
|||||||
The medium tabs are enum-driven — a fourth medium adds a tab automatically; only a label-lookup
|
The medium tabs are enum-driven — a fourth medium adds a tab automatically; only a label-lookup
|
||||||
entry (MediumTabLabels) and a content arm (MediumGrid) are needed, no markup fork. Selecting a
|
entry (MediumTabLabels) and a content arm (MediumGrid) are needed, no markup fork. Selecting a
|
||||||
tab swaps the grid below in place; no navigation to a separate page occurs. *@
|
tab swaps the grid below in place; no navigation to a separate page occurs. *@
|
||||||
<MudTabs Elevation="0" Rounded="true" ApplyEffectsToContainer="true" PanelClass="pt-4">
|
@* Medium-aware Add Track (§8.E): the button lives in the tab-strip chrome (not inside any grid
|
||||||
|
component — 8.C owns those) and reflects the active tab. It pre-selects the upload form to the
|
||||||
|
tab's medium via a single query-param (?medium=…); the ALL tab defaults to Cut. The medium is a
|
||||||
|
seed only — the upload form's selector stays user-changeable after landing. *@
|
||||||
|
<MudStack Row="true" Justify="Justify.FlexEnd" Class="mb-2">
|
||||||
|
<MudButton Variant="Variant.Filled"
|
||||||
|
Color="Color.Primary"
|
||||||
|
StartIcon="@Icons.Material.Filled.Add"
|
||||||
|
Href="@AddTrackHref(ActiveMedium)">
|
||||||
|
Add Track
|
||||||
|
</MudButton>
|
||||||
|
</MudStack>
|
||||||
|
|
||||||
|
<MudTabs Elevation="0" Rounded="true" ApplyEffectsToContainer="true" PanelClass="pt-4"
|
||||||
|
@bind-ActivePanelIndex="_activeTabIndex">
|
||||||
<MudTabPanel Text="ALL">
|
<MudTabPanel Text="ALL">
|
||||||
<CmsAllReleasesGrid OnReleasesChanged="OnAlbumsChanged" />
|
<CmsAllReleasesGrid OnReleasesChanged="OnAlbumsChanged" />
|
||||||
</MudTabPanel>
|
</MudTabPanel>
|
||||||
@@ -87,6 +101,21 @@
|
|||||||
@code {
|
@code {
|
||||||
private CmsTrackGrid? _grid;
|
private CmsTrackGrid? _grid;
|
||||||
|
|
||||||
|
// Active Release-Archive tab. Panel 0 is ALL; panels 1.. map to Enum.GetValues<ReleaseMedium>() in
|
||||||
|
// order. Drives the medium-aware Add Track button (§8.E).
|
||||||
|
private int _activeTabIndex;
|
||||||
|
|
||||||
|
// The medium the Add Track button pre-selects for the active tab. ALL (panel 0) defaults to Cut
|
||||||
|
// (Daniel, 2026-06-13); each medium tab maps to its enum value by position, so a fourth medium tab
|
||||||
|
// gets a correct Add Track for free — no markup fork.
|
||||||
|
private ReleaseMedium ActiveMedium =>
|
||||||
|
_activeTabIndex <= 0 ? ReleaseMedium.Cut : Enum.GetValues<ReleaseMedium>()[_activeTabIndex - 1];
|
||||||
|
|
||||||
|
// Single query-param convention: the upload page reads ?medium=… and seeds its selector (which stays
|
||||||
|
// user-changeable). Always explicit, including ALL→cut, so the link is unambiguous.
|
||||||
|
private static string AddTrackHref(ReleaseMedium medium) =>
|
||||||
|
$"/tracks/upload?medium={medium.ToString().ToLowerInvariant()}";
|
||||||
|
|
||||||
// Medium → tab label. The one place medium display text lives for the tab strip; a future medium adds
|
// Medium → tab label. The one place medium display text lives for the tab strip; a future medium adds
|
||||||
// one entry here and surfaces a tab automatically. Mirrors the extension discipline the retired
|
// one entry here and surfaces a tab automatically. Mirrors the extension discipline the retired
|
||||||
// ReleaseArchiveBrowser used for its cards. The ALL tab is rendered separately (it is not a medium).
|
// ReleaseArchiveBrowser used for its cards. The ALL tab is rendered separately (it is not a medium).
|
||||||
|
|||||||
Reference in New Issue
Block a user