Move campaign selector into header
This commit is contained in:
@@ -1,9 +1,8 @@
|
||||
@using Microsoft.AspNetCore.Components
|
||||
@using Microsoft.AspNetCore.Components
|
||||
@using RpgRoller.Components.Pages.HomeControls
|
||||
|
||||
<CampaignManagementPanel
|
||||
Campaigns="Workspace.State.Campaigns"
|
||||
SelectedCampaignId="Workspace.State.SelectedCampaignId"
|
||||
SelectedCampaign="Workspace.State.SelectedCampaign"
|
||||
Rulesets="Workspace.State.Rulesets"
|
||||
IsMutating="Workspace.State.IsMutating"
|
||||
@@ -11,7 +10,6 @@
|
||||
CanEditCharacter="Workspace.Campaigns.CanEditCharacter"
|
||||
CanDeleteCharacter="Workspace.Campaigns.CanDeleteCharacter"
|
||||
CanDeleteCampaign="Workspace.State.CanDeleteSelectedCampaign"
|
||||
CampaignSelectionChanged="OnCampaignSelectionChangedAsync"
|
||||
CampaignCreated="Workspace.Campaigns.OnCampaignCreatedAsync"
|
||||
DeleteCampaignRequested="Workspace.Campaigns.DeleteSelectedCampaignAsync"
|
||||
CreateCharacterRequested="Workspace.Campaigns.OpenCreateCharacterModal"
|
||||
@@ -22,10 +20,4 @@
|
||||
|
||||
@code {
|
||||
[Parameter, EditorRequired] public WorkspacePageContext Workspace { get; set; } = null!;
|
||||
|
||||
private async Task OnCampaignSelectionChangedAsync(ChangeEventArgs args)
|
||||
{
|
||||
await Workspace.Campaigns.OnCampaignSelectionChangedAsync(args);
|
||||
await Workspace.RequestRefreshAsync();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<header class="workspace-header">
|
||||
<header class="workspace-header">
|
||||
<div class="header-row">
|
||||
<h1>@Title</h1>
|
||||
@if (User is null)
|
||||
@@ -15,7 +15,23 @@
|
||||
}
|
||||
@if (ShowCampaign)
|
||||
{
|
||||
<p class="header-campaign">Campaign: <strong>@(CampaignName ?? "No campaign selected")</strong></p>
|
||||
<div class="header-campaign">
|
||||
<label for="@CampaignSelectId">Campaign</label>
|
||||
@if (Campaigns.Count == 0)
|
||||
{
|
||||
<span>No campaigns yet</span>
|
||||
}
|
||||
else
|
||||
{
|
||||
<select id="@CampaignSelectId"
|
||||
@onchange="CampaignSelectionChanged">
|
||||
@foreach (var campaign in Campaigns)
|
||||
{
|
||||
<option value="@campaign.Id" selected="@(campaign.Id == SelectedCampaignId)">@campaign.Name</option>
|
||||
}
|
||||
</select>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
<div class="header-connection-cell">
|
||||
@if (ShowConnectionState)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using RpgRoller.Contracts;
|
||||
|
||||
@@ -18,7 +18,13 @@ public partial class AppHeader
|
||||
|
||||
[Parameter] public bool ShowCampaign { get; set; }
|
||||
|
||||
[Parameter] public string? CampaignName { get; set; }
|
||||
[Parameter] public IReadOnlyList<CampaignSummary> Campaigns { get; set; } = [];
|
||||
|
||||
[Parameter] public Guid? SelectedCampaignId { get; set; }
|
||||
|
||||
[Parameter] public string CampaignSelectId { get; set; } = "header-campaign-select";
|
||||
|
||||
[Parameter] public EventCallback<ChangeEventArgs> CampaignSelectionChanged { get; set; }
|
||||
|
||||
[Parameter] public bool ShowConnectionState { get; set; } = true;
|
||||
|
||||
@@ -44,4 +50,4 @@ public sealed class AppHeaderMenuItem
|
||||
public string Label { get; init; } = string.Empty;
|
||||
public bool IsActive { get; init; }
|
||||
public Func<Task>? OnSelected { get; init; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<main class="management-screen">
|
||||
<main class="management-screen">
|
||||
<section class="card">
|
||||
<div class="section-head">
|
||||
<h2>Campaign</h2>
|
||||
@@ -9,13 +9,14 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
<label for="campaign-select">Current campaign</label>
|
||||
<select id="campaign-select" @onchange="CampaignSelectionChanged">
|
||||
@foreach (var campaign in Campaigns)
|
||||
<div class="campaign-current">
|
||||
<span>Current campaign</span>
|
||||
<strong>@(SelectedCampaign is null ? "No campaign selected" : SelectedCampaign.Name)</strong>
|
||||
@if (SelectedCampaign is not null)
|
||||
{
|
||||
<option value="@campaign.Id" selected="@(campaign.Id == SelectedCampaignId)">@campaign.Name (@campaign.RulesetId), GM: @campaign.Gm.DisplayName, @campaign.CharacterCount characters</option>
|
||||
<p>@SelectedCampaign.RulesetId, GM: @SelectedCampaign.Gm.DisplayName, @SelectedCampaign.Characters.Length characters</p>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
}
|
||||
|
||||
<button type="button"
|
||||
@@ -129,4 +130,4 @@
|
||||
</form>
|
||||
</section>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using RpgRoller.Contracts;
|
||||
|
||||
@@ -74,9 +74,6 @@ public partial class CampaignManagementPanel
|
||||
[Parameter]
|
||||
public IReadOnlyList<CampaignSummary> Campaigns { get; set; } = [];
|
||||
|
||||
[Parameter]
|
||||
public Guid? SelectedCampaignId { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public CampaignRoster? SelectedCampaign { get; set; }
|
||||
|
||||
@@ -98,9 +95,6 @@ public partial class CampaignManagementPanel
|
||||
[Parameter]
|
||||
public bool CanDeleteCampaign { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<ChangeEventArgs> CampaignSelectionChanged { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<Guid> CampaignCreated { get; set; }
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<section class="card character-panel">
|
||||
<section class="card character-panel">
|
||||
@if (IsCampaignDataLoading)
|
||||
{
|
||||
<div class="skeleton-stack">
|
||||
@@ -9,7 +9,7 @@
|
||||
}
|
||||
else if (SelectedCampaign is null)
|
||||
{
|
||||
<p class="empty">No campaign selected. Choose one in Campaign Management.</p>
|
||||
<p class="empty">No campaign selected. Choose one in the header.</p>
|
||||
}
|
||||
else if (SelectedCampaign.Characters.Length == 0)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@using RpgRoller.Components.Pages.HomeControls
|
||||
@using RpgRoller.Components.Pages.HomeControls
|
||||
<div class="@AppCssClass">
|
||||
<p class="sr-only" aria-live="polite">@State.LiveAnnouncement</p>
|
||||
|
||||
@@ -17,7 +17,9 @@
|
||||
<AppHeader
|
||||
User="State.User"
|
||||
ShowCampaign="@ShowCampaignInHeader"
|
||||
CampaignName="@State.SelectedCampaignName"
|
||||
Campaigns="State.Campaigns"
|
||||
SelectedCampaignId="State.SelectedCampaignId"
|
||||
CampaignSelectionChanged="OnHeaderCampaignSelectionChangedAsync"
|
||||
ShowConnectionState="@ShowConnectionStateInHeader"
|
||||
ConnectionStateLabel="@State.ConnectionStateLabel"
|
||||
ConnectionStateCssClass="@State.ConnectionStateCssClass"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.JSInterop;
|
||||
using RpgRoller.Components.Pages.HomeControls;
|
||||
@@ -84,6 +84,12 @@ public partial class Workspace : IAsyncDisposable
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private async Task OnHeaderCampaignSelectionChangedAsync(ChangeEventArgs args)
|
||||
{
|
||||
await Campaigns.OnCampaignSelectionChangedAsync(args);
|
||||
await RequestRefreshAsync();
|
||||
}
|
||||
|
||||
private Task RedirectToPlayAsync()
|
||||
{
|
||||
if (IsPlayRoute)
|
||||
@@ -220,4 +226,4 @@ public partial class Workspace : IAsyncDisposable
|
||||
private WorkspaceCampaignScopeCoordinator? m_Scope;
|
||||
private WorkspaceSessionCoordinator? m_Session;
|
||||
private Task? InitializationTask { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using RpgRoller.Components.Pages.HomeControls;
|
||||
using RpgRoller.Components.Pages.HomeControls;
|
||||
using RpgRoller.Contracts;
|
||||
using RpgRoller.Domain;
|
||||
|
||||
@@ -91,10 +91,6 @@ public sealed class WorkspaceState
|
||||
public HashSet<Guid> CampaignLogDetailsLoading { get; } = [];
|
||||
public Dictionary<Guid, string> CampaignLogDetailErrors { get; } = [];
|
||||
|
||||
public string? SelectedCampaignName => SelectedCampaign?.Name ??
|
||||
Campaigns.FirstOrDefault(campaign => campaign.Id == SelectedCampaignId)
|
||||
?.Name;
|
||||
|
||||
public CharacterSummary? SelectedCharacter =>
|
||||
SelectedCampaign?.Characters.FirstOrDefault(character => character.Id == SelectedCharacterId);
|
||||
|
||||
@@ -185,4 +181,4 @@ public sealed class WorkspaceState
|
||||
"reconnecting" => "warn",
|
||||
_ => "offline"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
:root {
|
||||
:root {
|
||||
--bg-top: #f7f0d8;
|
||||
--bg-bottom: #ecdfc4;
|
||||
--button-hover: #dccfb4;
|
||||
@@ -120,14 +120,33 @@ h3 {
|
||||
font-size: 1.15rem;
|
||||
}
|
||||
|
||||
.header-identity,
|
||||
.header-campaign {
|
||||
.header-identity {
|
||||
margin: 0;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.header-campaign {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.35rem;
|
||||
color: var(--muted);
|
||||
min-width: 12rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.header-campaign label {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.header-campaign select {
|
||||
max-width: 16rem;
|
||||
min-width: 9rem;
|
||||
padding: 0.25rem 0.45rem;
|
||||
}
|
||||
|
||||
.header-campaign span {
|
||||
font-weight: 700;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.header-connection-cell {
|
||||
@@ -156,6 +175,20 @@ h3 {
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.campaign-current {
|
||||
display: grid;
|
||||
gap: 0.15rem;
|
||||
}
|
||||
|
||||
.campaign-current span,
|
||||
.campaign-current p {
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.campaign-current p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.auth-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
@@ -1180,6 +1213,15 @@ select:focus-visible {
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.header-campaign {
|
||||
flex-wrap: wrap;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.header-campaign select {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.mobile-bottom-nav {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user