96 lines
4.4 KiB
Plaintext
96 lines
4.4 KiB
Plaintext
@model WritingContextDisplayViewModel
|
|
@{
|
|
var scene = Model.Context!.Scene!;
|
|
var floorPlan = Model.FloorPlan;
|
|
var floorId = scene.InitialFloorPlanFloorID
|
|
?? floorPlan?.OccupancyScenes.FirstOrDefault(x => x.SceneID == scene.SceneID)?.InitialFloorPlanFloorID
|
|
?? floorPlan?.Floors.OrderBy(x => x.SortOrder).FirstOrDefault()?.FloorPlanFloorID;
|
|
var floor = floorPlan?.Floors.FirstOrDefault(x => x.FloorPlanFloorID == floorId);
|
|
var blocks = floor is null ? [] : floorPlan!.Blocks.Where(x => x.FloorPlanFloorID == floor.FloorPlanFloorID).ToList();
|
|
var tokens = floor is null ? [] : floorPlan!.OccupancyTokens.Where(x => x.SceneID == scene.SceneID && x.FloorPlanFloorID == floor.FloorPlanFloorID).ToList();
|
|
var tokensByLocation = tokens.GroupBy(x => x.LocationID).ToDictionary(x => x.Key, x => x.ToList());
|
|
static string TextOr(string? value, string fallback) => string.IsNullOrWhiteSpace(value) ? fallback : value.Trim();
|
|
}
|
|
|
|
<div class="writing-context-grid writing-context-grid--place">
|
|
<article class="writing-context-card">
|
|
<p class="eyebrow">Location</p>
|
|
<h3>@TextOr(scene.LocationOptions.FirstOrDefault(x => x.Value == scene.PrimaryLocationID?.ToString())?.Text, "No primary location")</h3>
|
|
<dl class="writing-context-facts">
|
|
<dt>Floor plan</dt><dd>@(floorPlan?.FloorPlan.Name ?? "No floor plan linked to this scene")</dd>
|
|
<dt>Floor</dt><dd>@(floor?.Name ?? "No floor selected")</dd>
|
|
</dl>
|
|
</article>
|
|
|
|
<article class="writing-context-card writing-context-card--wide">
|
|
<p class="eyebrow">Occupancy</p>
|
|
@if (floorPlan is null)
|
|
{
|
|
<p>No floor plan linked to this scene.</p>
|
|
}
|
|
else if (floor is null || !blocks.Any())
|
|
{
|
|
<p>No placed rooms are available for this floor.</p>
|
|
}
|
|
else
|
|
{
|
|
<div class="writing-context-floor"
|
|
style="--floor-cols:@floor.GridWidth;--floor-rows:@floor.GridHeight;"
|
|
aria-label="@floor.Name floor plan">
|
|
@foreach (var block in blocks)
|
|
{
|
|
var locationTokens = block.LocationID.HasValue && tokensByLocation.TryGetValue(block.LocationID.Value, out var blockTokens)
|
|
? blockTokens
|
|
: [];
|
|
<div class="writing-context-floor-block"
|
|
style="grid-column:@(block.X + 1) / span @block.WidthCells;grid-row:@(block.Y + 1) / span @block.HeightCells;">
|
|
<strong>@block.DisplayLabel</strong>
|
|
@if (locationTokens.Any())
|
|
{
|
|
<span>@string.Join(", ", locationTokens.Select(x => x.DisplayName).Take(3))@(locationTokens.Count > 3 ? $" +{locationTokens.Count - 3}" : string.Empty)</span>
|
|
}
|
|
</div>
|
|
}
|
|
</div>
|
|
}
|
|
</article>
|
|
|
|
<article class="writing-context-card">
|
|
<p class="eyebrow">Characters</p>
|
|
@if (!scene.SceneCharacters.Any(x => !string.IsNullOrWhiteSpace(x.LocationName) || !string.IsNullOrWhiteSpace(x.LocationPath)))
|
|
{
|
|
<p>No character locations recorded.</p>
|
|
}
|
|
else
|
|
{
|
|
<ul class="writing-context-list">
|
|
@foreach (var character in scene.SceneCharacters.Where(x => !string.IsNullOrWhiteSpace(x.LocationName) || !string.IsNullOrWhiteSpace(x.LocationPath)))
|
|
{
|
|
<li><strong>@character.CharacterName</strong> @TextOr(character.LocationPath ?? character.LocationName, "Unknown")</li>
|
|
}
|
|
</ul>
|
|
}
|
|
</article>
|
|
|
|
<article class="writing-context-card">
|
|
<p class="eyebrow">Assets</p>
|
|
@if (!scene.SceneAssetLocations.Any() && !scene.AssetCustodyEvents.Any())
|
|
{
|
|
<p>No asset locations or custody changes recorded.</p>
|
|
}
|
|
else
|
|
{
|
|
<ul class="writing-context-list">
|
|
@foreach (var asset in scene.SceneAssetLocations.Take(6))
|
|
{
|
|
<li><strong>@asset.AssetName</strong> @asset.LocationPath</li>
|
|
}
|
|
@foreach (var custody in scene.AssetCustodyEvents.Take(6))
|
|
{
|
|
<li><strong>@custody.AssetName</strong> @TextOr(custody.CustodianSummary, custody.CustodyEventTypeName)</li>
|
|
}
|
|
</ul>
|
|
}
|
|
</article>
|
|
</div>
|