PlotDirector/PlotLine/Views/Development/StoryIntelligenceExperience.cshtml

463 lines
22 KiB
Plaintext

@using System.Text.Json
@model StoryIntelligenceExperiencePrototypeViewModel
@{
Layout = null;
var jsonOptions = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
var statusLabel = Model.Mode switch
{
"simulation" => "Simulation",
"real" when Model.IsTerminal => "Analysis Complete",
"real" => "Live Analysis",
"error" => "Import Session Error",
_ => "Select Import Session"
};
var sourceLabel = Model.Mode switch
{
"simulation" => "Simulation only",
"real" => "Real snapshot",
"error" => "No live snapshot",
_ => "Choose a session"
};
var bootModel = Model.Mode == "real"
? new StoryIntelligenceExperiencePrototypeViewModel
{
Mode = Model.Mode,
RunId = Model.RunId,
ImportSessionId = Model.ImportSessionId,
BookId = Model.BookId,
RunStatus = Model.RunStatus,
GeneratedUtc = Model.GeneratedUtc,
IsTerminal = false,
ProjectName = Model.ProjectName,
BookTitle = Model.BookTitle,
SnapshotMessage = Model.SnapshotMessage,
Diagnostics = Model.Diagnostics,
Scenes = Model.Scenes,
ChangeToken = Model.ChangeToken
}
: Model;
}
<!DOCTYPE html>
<html lang="en" data-theme="dark" data-bs-theme="dark">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Story Intelligence Experience Prototype - PlotDirector</title>
<link rel="stylesheet" href="~/css/story-intelligence-experience-prototype.css" asp-append-version="true" />
</head>
<body>
<script id="storyExperienceData" type="application/json">@Html.Raw(JsonSerializer.Serialize(bootModel, jsonOptions))</script>
<main class="story-exp"
data-story-experience
data-image-diagnostics="true"
data-mode="@Model.Mode"
data-run-id="@Model.RunId"
data-book-id="@Model.BookId"
data-import-session-id="@Model.ImportSessionId"
data-snapshot-url="@(Model.ImportSessionId.HasValue ? $"/api/story-intelligence/import-sessions/{Model.ImportSessionId.Value}/visualisation-snapshot" : Model.RunId.HasValue ? $"/api/story-intelligence/runs/{Model.RunId.Value}/visualisation-snapshot" : string.Empty)"
data-change-token="@Model.ChangeToken"
data-terminal="@Model.IsTerminal.ToString().ToLowerInvariant()">
<header class="story-exp-header" aria-label="Story Intelligence status">
<div class="story-exp-brand">
<strong>PlotDirector</strong>
<span>Story Intelligence</span>
</div>
<div class="story-exp-context">
<span data-experience-status>@statusLabel</span>
<span data-project-name>@Model.ProjectName</span>
<span data-book-title>@Model.BookTitle</span>
<span data-stage-label>Preparing</span>
<span>Scene <strong data-current-scene>1</strong></span>
</div>
@if (Model.Mode == "real" && Model.BookId.HasValue)
{
<a class="story-exp-background" href="/onboarding/story-intelligence/book/@Model.BookId.Value/continue">Return to Import</a>
}
else
{
<a class="story-exp-background" href="/Development/StoryIntelligenceExperience?mode=simulation">Simulation</a>
}
</header>
@if (Model.AvailableRuns.Count > 0)
{
<nav class="story-exp-run-selector" aria-label="Development Story Intelligence import sessions">
<strong>Story Intelligence import sessions</strong>
@foreach (var run in Model.AvailableRuns)
{
<a href="/Development/StoryIntelligenceExperience?importSessionId=@run.ImportSessionId">@run.Label</a>
}
</nav>
}
@if (!string.IsNullOrWhiteSpace(Model.SnapshotMessage))
{
<aside class="story-exp-status-message" role="status" data-snapshot-message>
@Model.SnapshotMessage
</aside>
}
<section class="story-exp-shell" aria-label="Story Intelligence visual prototype">
<aside class="story-exp-left" aria-label="Analysis progress">
<div class="story-exp-progress">
<p class="story-exp-eyebrow">Overall progress</p>
<div class="story-exp-progress-ring" aria-hidden="true">
<div class="story-exp-progress-orbit"></div>
<div class="story-exp-progress-core">
<strong data-progress-percent>0%</strong>
<span>complete</span>
</div>
</div>
<div class="story-exp-progress-times">
<div>
<span>Elapsed</span>
<strong data-elapsed-time>0m</strong>
</div>
<div>
<span>Remaining</span>
<strong data-estimated-remaining>Calculating</strong>
</div>
</div>
</div>
<dl class="story-exp-stats">
<div>
<dt>Chapters analysed</dt>
<dd data-chapter-count>0 of 5</dd>
</div>
<div>
<dt>Scenes analysed</dt>
<dd data-scene-count>0 of 12</dd>
</div>
<div>
<dt>Current stage</dt>
<dd data-current-stage>Preparing</dd>
</div>
</dl>
<section class="story-exp-panel" aria-labelledby="latest-discoveries-title">
<h2 id="latest-discoveries-title">Latest discoveries</h2>
<ul class="story-exp-list" data-discoveries></ul>
</section>
<section class="story-exp-panel" aria-labelledby="activity-feed-title">
<h2 id="activity-feed-title">Live activity</h2>
<ol class="story-exp-feed" data-activity-feed></ol>
</section>
</aside>
<section class="story-exp-stage" aria-labelledby="living-story-title">
<div class="story-exp-stage-copy">
<p class="story-exp-eyebrow">Living story view</p>
<h1 id="living-story-title" data-scene-title>Reading the manuscript</h1>
<p data-scene-summary></p>
</div>
<div class="story-exp-visual" data-visual-stage>
<svg class="story-exp-connections" data-connections aria-hidden="true"></svg>
<div class="story-exp-zone story-exp-zone--characters" aria-label="Characters">
<p class="story-exp-zone-label">Characters</p>
<div class="story-exp-characters" data-characters></div>
</div>
<div class="story-exp-zone story-exp-zone--location" aria-label="Active location">
<p class="story-exp-zone-label">Location</p>
<div class="story-exp-location" data-location></div>
</div>
<div class="story-exp-zone story-exp-zone--assets" aria-label="Significant assets">
<p class="story-exp-zone-label">Assets</p>
<div class="story-exp-assets" data-assets></div>
</div>
</div>
<section class="story-exp-ribbon-wrap" aria-label="Recent scenes and timeline">
<div class="story-exp-ribbon" data-scene-ribbon></div>
<div class="story-exp-timeline" data-timeline></div>
</section>
</section>
<aside class="story-exp-right" aria-label="Story understanding">
<section class="story-exp-panel" aria-labelledby="relationships-title">
<h2 id="relationships-title">Relationship changes</h2>
<div class="story-exp-insight-list" data-relationships></div>
</section>
<section class="story-exp-panel" aria-labelledby="knowledge-title">
<h2 id="knowledge-title">Knowledge threads</h2>
<div class="story-exp-insight-list" data-knowledge></div>
</section>
<section class="story-exp-panel" aria-labelledby="observations-title">
<h2 id="observations-title">Story observations</h2>
<div class="story-exp-insight-list" data-observations></div>
</section>
</aside>
</section>
@if (Model.Mode == "simulation")
{
<aside class="story-exp-controls" aria-label="Prototype controls">
<div>
<span>Prototype controls</span>
<small>@sourceLabel</small>
</div>
<button type="button" data-control="restart">Restart</button>
<button type="button" data-control="previous">Previous</button>
<button type="button" data-control="play">Pause</button>
<button type="button" data-control="next">Next</button>
<label>
Speed
<input type="range" min="3500" max="10000" step="500" value="6200" data-speed-control />
</label>
</aside>
}
<details class="story-exp-diagnostics" data-diagnostics>
<summary>Diagnostics</summary>
<dl>
<div>
<dt>Current Import ID</dt>
<dd data-diagnostic-key="currentImportId">@Model.Diagnostics.CurrentImportId</dd>
</div>
<div>
<dt>Requested mode</dt>
<dd data-diagnostic-key="requestedMode">@Model.Diagnostics.RequestedMode</dd>
</div>
<div>
<dt>Requested ImportSessionID</dt>
<dd data-diagnostic-key="requestedImportSessionId">@Model.Diagnostics.RequestedImportSessionId</dd>
</div>
<div>
<dt>Resolved ImportSessionID</dt>
<dd data-diagnostic-key="resolvedImportSessionId">@Model.Diagnostics.ResolvedImportSessionId</dd>
</div>
<div>
<dt>Active chapter RunID</dt>
<dd data-diagnostic-key="activeChapterRunId">@Model.Diagnostics.ActiveChapterRunId</dd>
</div>
<div>
<dt>Session status</dt>
<dd data-diagnostic-key="sessionStatus">@Model.Diagnostics.SessionStatus</dd>
</div>
<div>
<dt>Overall book progress</dt>
<dd data-diagnostic-key="overallBookProgress">@Model.Diagnostics.OverallBookProgress</dd>
</div>
<div>
<dt>Authoritative import progress</dt>
<dd data-diagnostic-key="authoritativeImportProgress">@Model.Diagnostics.AuthoritativeImportProgress</dd>
</div>
<div>
<dt>Calculated visualisation progress</dt>
<dd data-diagnostic-key="calculatedVisualisationProgress">@Model.Diagnostics.CalculatedVisualisationProgress</dd>
</div>
<div>
<dt>Total chapters</dt>
<dd data-diagnostic-key="totalChapters">@Model.Diagnostics.TotalChapters</dd>
</div>
<div>
<dt>Completed chapters</dt>
<dd data-diagnostic-key="completedChapters">@Model.Diagnostics.CompletedChapters</dd>
</div>
<div>
<dt>Current chapter</dt>
<dd data-diagnostic-key="currentChapter">@Model.Diagnostics.CurrentChapter</dd>
</div>
<div>
<dt>Current scene</dt>
<dd data-diagnostic-key="currentScene">@Model.Diagnostics.CurrentScene</dd>
</div>
<div>
<dt>Completed scenes</dt>
<dd data-diagnostic-key="completedScenes">@Model.Diagnostics.CompletedScenes</dd>
</div>
<div>
<dt>Total scenes</dt>
<dd data-diagnostic-key="totalScenes">@Model.Diagnostics.TotalScenes</dd>
</div>
<div>
<dt>Parsed scenes</dt>
<dd data-diagnostic-key="parsedScenes">@Model.Diagnostics.ParsedScenes</dd>
</div>
<div>
<dt>Terminal run/session status</dt>
<dd data-diagnostic-key="terminalRunSessionStatus">@Model.Diagnostics.TerminalRunSessionStatus</dd>
</div>
<div>
<dt>Displayed progress reason</dt>
<dd data-diagnostic-key="displayedProgressReason">@Model.Diagnostics.DisplayedProgressReason</dd>
</div>
<div>
<dt>Progress source</dt>
<dd data-diagnostic-key="progressSource">@Model.Diagnostics.ProgressSource</dd>
</div>
<div>
<dt>Current backend stage</dt>
<dd data-diagnostic-key="currentBackendStage">@Model.Diagnostics.CurrentBackendStage</dd>
</div>
<div>
<dt>Story Memory character count</dt>
<dd data-diagnostic-key="storyMemoryCharacterCount">@Model.Diagnostics.StoryMemoryCharacterCount</dd>
</div>
<div>
<dt>Resolved characters</dt>
<dd data-diagnostic-key="resolvedCharacterCount">@Model.Diagnostics.ResolvedCharacterCount</dd>
</div>
<div>
<dt>Unresolved characters</dt>
<dd data-diagnostic-key="unresolvedCharacterCount">@Model.Diagnostics.UnresolvedCharacterCount</dd>
</div>
<div>
<dt>Narrator confidence</dt>
<dd data-diagnostic-key="narratorConfidence">@Model.Diagnostics.NarratorConfidence</dd>
</div>
<div>
<dt>Raw scene POV</dt>
<dd data-diagnostic-key="rawScenePov">@Model.Diagnostics.RawScenePov</dd>
</div>
<div>
<dt>Inherited chapter POV</dt>
<dd data-diagnostic-key="inheritedChapterPov">@Model.Diagnostics.InheritedChapterPov</dd>
</div>
<div>
<dt>Resolved POV identity</dt>
<dd data-diagnostic-key="resolvedPovIdentity">@Model.Diagnostics.ResolvedPovIdentity</dd>
</div>
<div>
<dt>POV resolution reason</dt>
<dd data-diagnostic-key="povResolutionReason">@Model.Diagnostics.PovResolutionReason</dd>
</div>
<div>
<dt>POV confidence</dt>
<dd data-diagnostic-key="povConfidence">@Model.Diagnostics.PovConfidence</dd>
</div>
<div>
<dt>POV change detected</dt>
<dd data-diagnostic-key="povChangeDetected">@Model.Diagnostics.PovChangeDetected</dd>
</div>
<div>
<dt>Illustration assignments</dt>
<dd data-diagnostic-key="illustrationAssignmentCount">@Model.Diagnostics.IllustrationAssignmentCount</dd>
</div>
<div>
<dt>Illustration changes</dt>
<dd data-diagnostic-key="illustrationChangeCount">@Model.Diagnostics.IllustrationChangeCount</dd>
</div>
<div>
<dt>Character consistency report</dt>
<dd data-diagnostic-key="characterConsistencyReport">@Model.Diagnostics.CharacterConsistencyReport</dd>
</div>
<div>
<dt>Current polling interval</dt>
<dd data-diagnostic-key="currentPollingInterval">Initial</dd>
</div>
<div>
<dt>Latest snapshot age</dt>
<dd data-diagnostic-key="latestSnapshotAge">Initial</dd>
</div>
<div>
<dt>Snapshot source</dt>
<dd data-diagnostic-key="snapshotSource">@Model.Diagnostics.SnapshotSource</dd>
</div>
<div>
<dt>Current Snapshot Version</dt>
<dd data-diagnostics-current>0</dd>
</div>
<div>
<dt>Previous Snapshot Version</dt>
<dd data-diagnostics-previous>0</dd>
</div>
<div>
<dt>Change Token</dt>
<dd data-diagnostics-token>@Model.ChangeToken</dd>
</div>
<div>
<dt>Animation Queue Length</dt>
<dd data-diagnostics-queue>0</dd>
</div>
<div>
<dt>Last Refresh Time</dt>
<dd data-diagnostics-refresh>Initial</dd>
</div>
<div>
<dt>Snapshot Build Time</dt>
<dd data-diagnostics-build>0ms</dd>
</div>
<div>
<dt>Operations detected</dt>
<dd data-diagnostics-operations>InitialRender</dd>
</div>
<div>
<dt>Run status</dt>
<dd data-diagnostic-key="runStatus">@Model.Diagnostics.RunStatus</dd>
</div>
<div>
<dt>Persisted completed scenes</dt>
<dd data-diagnostic-key="persistedCompletedSceneCount">@Model.Diagnostics.PersistedCompletedSceneCount</dd>
</div>
<div>
<dt>Total persisted scene results</dt>
<dd data-diagnostic-key="totalPersistedSceneResultCount">@Model.Diagnostics.TotalPersistedSceneResultCount</dd>
</div>
<div>
<dt>Successfully parsed scene results</dt>
<dd data-diagnostic-key="successfullyParsedSceneResultCount">@Model.Diagnostics.SuccessfullyParsedSceneResultCount</dd>
</div>
<div>
<dt>Failed/unparseable scene results</dt>
<dd data-diagnostic-key="failedSceneResultCount">@Model.Diagnostics.FailedSceneResultCount</dd>
</div>
<div>
<dt>Highest persisted SceneResultID</dt>
<dd data-diagnostic-key="highestPersistedSceneResultId">@Model.Diagnostics.HighestPersistedSceneResultId</dd>
</div>
<div>
<dt>Highest parsed SceneResultID</dt>
<dd data-diagnostic-key="highestParsedSceneResultId">@Model.Diagnostics.HighestParsedSceneResultId</dd>
</div>
<div>
<dt>Selected current SceneResultID</dt>
<dd data-diagnostic-key="selectedCurrentSceneResultId">@Model.Diagnostics.SelectedCurrentSceneResultId</dd>
</div>
<div>
<dt>Selected chapter and scene order</dt>
<dd data-diagnostic-key="selectedChapterAndSceneOrder">@Model.Diagnostics.SelectedChapterAndSceneOrder</dd>
</div>
<div>
<dt>Analysis cursor</dt>
<dd data-diagnostic-key="analysisCursor">@Model.Diagnostics.AnalysisCursor</dd>
</div>
<div>
<dt>Snapshot warning</dt>
<dd data-diagnostic-key="warning">@Model.Diagnostics.Warning</dd>
</div>
<div>
<dt>Last successful snapshot fetch</dt>
<dd data-diagnostic-key="lastSuccessfulSnapshotFetch">Initial</dd>
</div>
<div>
<dt>Last snapshot HTTP status</dt>
<dd data-diagnostic-key="lastSnapshotHttpStatus">Initial</dd>
</div>
<div>
<dt>Consecutive unchanged polls</dt>
<dd data-diagnostic-key="consecutiveUnchangedPolls">0</dd>
</div>
<div>
<dt>Consecutive failed polls</dt>
<dd data-diagnostic-key="consecutiveFailedPolls">0</dd>
</div>
<div>
<dt>Polling</dt>
<dd data-diagnostic-key="pollingActive">Initialising</dd>
</div>
<div>
<dt>Polling stopped reason</dt>
<dd data-diagnostic-key="pollingStoppedReason">none</dd>
</div>
</dl>
</details>
</main>
<script src="~/js/story-intelligence-experience-prototype.js" asp-append-version="true"></script>
</body>
</html>