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
|
@using RpgRoller.Components.Pages.HomeControls
|
||||||
|
|
||||||
<CampaignManagementPanel
|
<CampaignManagementPanel
|
||||||
Campaigns="Workspace.State.Campaigns"
|
Campaigns="Workspace.State.Campaigns"
|
||||||
SelectedCampaignId="Workspace.State.SelectedCampaignId"
|
|
||||||
SelectedCampaign="Workspace.State.SelectedCampaign"
|
SelectedCampaign="Workspace.State.SelectedCampaign"
|
||||||
Rulesets="Workspace.State.Rulesets"
|
Rulesets="Workspace.State.Rulesets"
|
||||||
IsMutating="Workspace.State.IsMutating"
|
IsMutating="Workspace.State.IsMutating"
|
||||||
@@ -11,7 +10,6 @@
|
|||||||
CanEditCharacter="Workspace.Campaigns.CanEditCharacter"
|
CanEditCharacter="Workspace.Campaigns.CanEditCharacter"
|
||||||
CanDeleteCharacter="Workspace.Campaigns.CanDeleteCharacter"
|
CanDeleteCharacter="Workspace.Campaigns.CanDeleteCharacter"
|
||||||
CanDeleteCampaign="Workspace.State.CanDeleteSelectedCampaign"
|
CanDeleteCampaign="Workspace.State.CanDeleteSelectedCampaign"
|
||||||
CampaignSelectionChanged="OnCampaignSelectionChangedAsync"
|
|
||||||
CampaignCreated="Workspace.Campaigns.OnCampaignCreatedAsync"
|
CampaignCreated="Workspace.Campaigns.OnCampaignCreatedAsync"
|
||||||
DeleteCampaignRequested="Workspace.Campaigns.DeleteSelectedCampaignAsync"
|
DeleteCampaignRequested="Workspace.Campaigns.DeleteSelectedCampaignAsync"
|
||||||
CreateCharacterRequested="Workspace.Campaigns.OpenCreateCharacterModal"
|
CreateCharacterRequested="Workspace.Campaigns.OpenCreateCharacterModal"
|
||||||
@@ -22,10 +20,4 @@
|
|||||||
|
|
||||||
@code {
|
@code {
|
||||||
[Parameter, EditorRequired] public WorkspacePageContext Workspace { get; set; } = null!;
|
[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">
|
<div class="header-row">
|
||||||
<h1>@Title</h1>
|
<h1>@Title</h1>
|
||||||
@if (User is null)
|
@if (User is null)
|
||||||
@@ -15,7 +15,23 @@
|
|||||||
}
|
}
|
||||||
@if (ShowCampaign)
|
@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">
|
<div class="header-connection-cell">
|
||||||
@if (ShowConnectionState)
|
@if (ShowConnectionState)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
using RpgRoller.Contracts;
|
using RpgRoller.Contracts;
|
||||||
|
|
||||||
@@ -18,7 +18,13 @@ public partial class AppHeader
|
|||||||
|
|
||||||
[Parameter] public bool ShowCampaign { get; set; }
|
[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;
|
[Parameter] public bool ShowConnectionState { get; set; } = true;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<main class="management-screen">
|
<main class="management-screen">
|
||||||
<section class="card">
|
<section class="card">
|
||||||
<div class="section-head">
|
<div class="section-head">
|
||||||
<h2>Campaign</h2>
|
<h2>Campaign</h2>
|
||||||
@@ -9,13 +9,14 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<label for="campaign-select">Current campaign</label>
|
<div class="campaign-current">
|
||||||
<select id="campaign-select" @onchange="CampaignSelectionChanged">
|
<span>Current campaign</span>
|
||||||
@foreach (var campaign in Campaigns)
|
<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"
|
<button type="button"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
using RpgRoller.Contracts;
|
using RpgRoller.Contracts;
|
||||||
|
|
||||||
@@ -74,9 +74,6 @@ public partial class CampaignManagementPanel
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public IReadOnlyList<CampaignSummary> Campaigns { get; set; } = [];
|
public IReadOnlyList<CampaignSummary> Campaigns { get; set; } = [];
|
||||||
|
|
||||||
[Parameter]
|
|
||||||
public Guid? SelectedCampaignId { get; set; }
|
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public CampaignRoster? SelectedCampaign { get; set; }
|
public CampaignRoster? SelectedCampaign { get; set; }
|
||||||
|
|
||||||
@@ -98,9 +95,6 @@ public partial class CampaignManagementPanel
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public bool CanDeleteCampaign { get; set; }
|
public bool CanDeleteCampaign { get; set; }
|
||||||
|
|
||||||
[Parameter]
|
|
||||||
public EventCallback<ChangeEventArgs> CampaignSelectionChanged { get; set; }
|
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public EventCallback<Guid> CampaignCreated { get; set; }
|
public EventCallback<Guid> CampaignCreated { get; set; }
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<section class="card character-panel">
|
<section class="card character-panel">
|
||||||
@if (IsCampaignDataLoading)
|
@if (IsCampaignDataLoading)
|
||||||
{
|
{
|
||||||
<div class="skeleton-stack">
|
<div class="skeleton-stack">
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
}
|
}
|
||||||
else if (SelectedCampaign is null)
|
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)
|
else if (SelectedCampaign.Characters.Length == 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
@using RpgRoller.Components.Pages.HomeControls
|
@using RpgRoller.Components.Pages.HomeControls
|
||||||
<div class="@AppCssClass">
|
<div class="@AppCssClass">
|
||||||
<p class="sr-only" aria-live="polite">@State.LiveAnnouncement</p>
|
<p class="sr-only" aria-live="polite">@State.LiveAnnouncement</p>
|
||||||
|
|
||||||
@@ -17,7 +17,9 @@
|
|||||||
<AppHeader
|
<AppHeader
|
||||||
User="State.User"
|
User="State.User"
|
||||||
ShowCampaign="@ShowCampaignInHeader"
|
ShowCampaign="@ShowCampaignInHeader"
|
||||||
CampaignName="@State.SelectedCampaignName"
|
Campaigns="State.Campaigns"
|
||||||
|
SelectedCampaignId="State.SelectedCampaignId"
|
||||||
|
CampaignSelectionChanged="OnHeaderCampaignSelectionChangedAsync"
|
||||||
ShowConnectionState="@ShowConnectionStateInHeader"
|
ShowConnectionState="@ShowConnectionStateInHeader"
|
||||||
ConnectionStateLabel="@State.ConnectionStateLabel"
|
ConnectionStateLabel="@State.ConnectionStateLabel"
|
||||||
ConnectionStateCssClass="@State.ConnectionStateCssClass"
|
ConnectionStateCssClass="@State.ConnectionStateCssClass"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
using Microsoft.JSInterop;
|
using Microsoft.JSInterop;
|
||||||
using RpgRoller.Components.Pages.HomeControls;
|
using RpgRoller.Components.Pages.HomeControls;
|
||||||
@@ -84,6 +84,12 @@ public partial class Workspace : IAsyncDisposable
|
|||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task OnHeaderCampaignSelectionChangedAsync(ChangeEventArgs args)
|
||||||
|
{
|
||||||
|
await Campaigns.OnCampaignSelectionChangedAsync(args);
|
||||||
|
await RequestRefreshAsync();
|
||||||
|
}
|
||||||
|
|
||||||
private Task RedirectToPlayAsync()
|
private Task RedirectToPlayAsync()
|
||||||
{
|
{
|
||||||
if (IsPlayRoute)
|
if (IsPlayRoute)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using RpgRoller.Components.Pages.HomeControls;
|
using RpgRoller.Components.Pages.HomeControls;
|
||||||
using RpgRoller.Contracts;
|
using RpgRoller.Contracts;
|
||||||
using RpgRoller.Domain;
|
using RpgRoller.Domain;
|
||||||
|
|
||||||
@@ -91,10 +91,6 @@ public sealed class WorkspaceState
|
|||||||
public HashSet<Guid> CampaignLogDetailsLoading { get; } = [];
|
public HashSet<Guid> CampaignLogDetailsLoading { get; } = [];
|
||||||
public Dictionary<Guid, string> CampaignLogDetailErrors { get; } = [];
|
public Dictionary<Guid, string> CampaignLogDetailErrors { get; } = [];
|
||||||
|
|
||||||
public string? SelectedCampaignName => SelectedCampaign?.Name ??
|
|
||||||
Campaigns.FirstOrDefault(campaign => campaign.Id == SelectedCampaignId)
|
|
||||||
?.Name;
|
|
||||||
|
|
||||||
public CharacterSummary? SelectedCharacter =>
|
public CharacterSummary? SelectedCharacter =>
|
||||||
SelectedCampaign?.Characters.FirstOrDefault(character => character.Id == SelectedCharacterId);
|
SelectedCampaign?.Characters.FirstOrDefault(character => character.Id == SelectedCharacterId);
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
:root {
|
:root {
|
||||||
--bg-top: #f7f0d8;
|
--bg-top: #f7f0d8;
|
||||||
--bg-bottom: #ecdfc4;
|
--bg-bottom: #ecdfc4;
|
||||||
--button-hover: #dccfb4;
|
--button-hover: #dccfb4;
|
||||||
@@ -120,14 +120,33 @@ h3 {
|
|||||||
font-size: 1.15rem;
|
font-size: 1.15rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-identity,
|
.header-identity {
|
||||||
.header-campaign {
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-campaign {
|
.header-campaign {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.35rem;
|
||||||
color: var(--muted);
|
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 {
|
.header-connection-cell {
|
||||||
@@ -156,6 +175,20 @@ h3 {
|
|||||||
gap: 0.75rem;
|
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 {
|
.auth-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
@@ -1180,6 +1213,15 @@ select:focus-visible {
|
|||||||
white-space: normal;
|
white-space: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.header-campaign {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-campaign select {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.mobile-bottom-nav {
|
.mobile-bottom-nav {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user