217 lines
9.3 KiB
Plaintext
217 lines
9.3 KiB
Plaintext
@model StoryIntelligenceProgressViewModel
|
|
@using System.Security.Claims
|
|
@inject IConfiguration Configuration
|
|
@{
|
|
ViewData["Title"] = "Review analysis";
|
|
var adminEmails = Configuration.GetSection("Admin:AllowedEmails").Get<string[]>() ?? [];
|
|
var userEmail = User.FindFirstValue(ClaimTypes.Email);
|
|
var isAdmin = !string.IsNullOrWhiteSpace(userEmail)
|
|
&& adminEmails.Any(email => string.Equals(email, userEmail, StringComparison.OrdinalIgnoreCase));
|
|
var chaptersNeedingReview = Model.Chapters.Count(NeedsReview);
|
|
var readyToCreate = Model.Chapters.Count(chapter => chapter.CanCommit);
|
|
}
|
|
|
|
<section class="onboarding-shell" aria-labelledby="story-review-title">
|
|
<div class="onboarding-panel onboarding-review-panel story-review-page">
|
|
<div class="onboarding-copy">
|
|
<p class="eyebrow">@Model.BookTitle</p>
|
|
<h1 id="story-review-title">Review analysis</h1>
|
|
<p>PlotDirector has finished reading your manuscript. Review the chapter results, then create scenes when you are ready.</p>
|
|
</div>
|
|
|
|
@if (TempData["OnboardingStoryIntelligenceError"] is string error)
|
|
{
|
|
<div class="alert alert-danger">@error</div>
|
|
}
|
|
@if (TempData["OnboardingStoryIntelligenceMessage"] is string message)
|
|
{
|
|
<div class="alert alert-success">@message</div>
|
|
}
|
|
|
|
<section class="alert alert-info">
|
|
Nothing is added to your project until you choose Create scenes. This step only creates scenes, summaries and supported scene notes.
|
|
</section>
|
|
|
|
<section class="story-review-summary" aria-label="Analysis summary">
|
|
<div>
|
|
<span>Chapters analysed</span>
|
|
<strong>@Model.CompletedChapterCount of @Model.ChapterCount</strong>
|
|
</div>
|
|
<div>
|
|
<span>Scenes found</span>
|
|
<strong>@Model.TotalDetectedScenes.ToString("N0")</strong>
|
|
</div>
|
|
<div>
|
|
<span>Ready to create</span>
|
|
<strong>@readyToCreate.ToString("N0")</strong>
|
|
</div>
|
|
<div>
|
|
<span>Needs review</span>
|
|
<strong>@chaptersNeedingReview.ToString("N0")</strong>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="story-review-chapter-list" aria-label="Chapter review">
|
|
@foreach (var chapter in Model.Chapters.OrderBy(chapter => chapter.ChapterNumber))
|
|
{
|
|
<article class="story-review-chapter-card">
|
|
<div class="story-review-chapter-heading">
|
|
<div>
|
|
<p class="eyebrow">Chapter @chapter.ChapterNumber</p>
|
|
<h2>@chapter.ChapterTitle</h2>
|
|
</div>
|
|
<strong class="@StatusClass(chapter)">@FriendlyStatus(chapter)</strong>
|
|
</div>
|
|
|
|
<div class="story-review-scene-panel">
|
|
<div>
|
|
<span>Scenes found</span>
|
|
<strong>@((chapter.TotalDetectedScenes ?? 0).ToString("N0"))</strong>
|
|
</div>
|
|
<div>
|
|
<span>Scenes ready</span>
|
|
<strong>@((chapter.CompletedScenes ?? 0).ToString("N0"))</strong>
|
|
</div>
|
|
<div>
|
|
<span>Needs review</span>
|
|
<strong>@(((chapter.FailedScenes ?? 0) + chapter.Blockers.Count).ToString("N0"))</strong>
|
|
</div>
|
|
</div>
|
|
|
|
@if (!string.IsNullOrWhiteSpace(chapter.CommitMessage))
|
|
{
|
|
<p class="story-review-note">@chapter.CommitMessage</p>
|
|
}
|
|
|
|
@if (chapter.Warnings.Count > 0)
|
|
{
|
|
<div class="story-review-note">
|
|
<strong>Notes</strong>
|
|
<ul>
|
|
@foreach (var warning in chapter.Warnings)
|
|
{
|
|
<li>@warning</li>
|
|
}
|
|
</ul>
|
|
</div>
|
|
}
|
|
|
|
@if (chapter.Blockers.Count > 0)
|
|
{
|
|
<div class="story-review-note story-review-note--warning">
|
|
<strong>Before scenes can be created</strong>
|
|
<ul>
|
|
@foreach (var blocker in chapter.Blockers)
|
|
{
|
|
<li>@blocker</li>
|
|
}
|
|
</ul>
|
|
</div>
|
|
}
|
|
|
|
@if (!string.IsNullOrWhiteSpace(chapter.ErrorMessage))
|
|
{
|
|
<p class="story-review-note story-review-note--warning">@chapter.ErrorMessage</p>
|
|
}
|
|
|
|
<div class="story-review-card-actions">
|
|
@if (chapter.HasCompletedCommit)
|
|
{
|
|
<button class="btn btn-outline-secondary" type="button" disabled>@chapter.ScenesCreated.ToString("N0") scene(s) created</button>
|
|
}
|
|
else if (chapter.CanCommit && Model.BatchID.HasValue)
|
|
{
|
|
<form asp-action="CommitStoryIntelligence" method="post">
|
|
<input type="hidden" name="batchId" value="@Model.BatchID" />
|
|
<input type="hidden" name="runId" value="@chapter.RunID" />
|
|
<button class="btn btn-primary" type="submit">Create scenes</button>
|
|
</form>
|
|
}
|
|
else if (chapter.IsActive && Model.BatchID.HasValue)
|
|
{
|
|
<a class="btn btn-outline-secondary" asp-action="StoryIntelligenceProgress" asp-route-batchId="@Model.BatchID">View progress</a>
|
|
}
|
|
else
|
|
{
|
|
<button class="btn btn-outline-secondary" type="button" disabled>Needs attention</button>
|
|
}
|
|
</div>
|
|
|
|
@if (isAdmin)
|
|
{
|
|
<details class="story-review-admin">
|
|
<summary>Admin diagnostics</summary>
|
|
<dl>
|
|
<div><dt>Run ID</dt><dd>@chapter.RunID</dd></div>
|
|
<div><dt>Status</dt><dd>@chapter.Status</dd></div>
|
|
<div><dt>Stage</dt><dd>@(chapter.CurrentStage ?? "-")</dd></div>
|
|
<div><dt>Failure stage</dt><dd>@(chapter.FailureStage ?? "-")</dd></div>
|
|
<div><dt>Tokens</dt><dd>@(chapter.TotalTokens?.ToString("N0") ?? "-")</dd></div>
|
|
</dl>
|
|
</details>
|
|
}
|
|
</article>
|
|
}
|
|
</section>
|
|
|
|
<div class="onboarding-actions">
|
|
@if (Model.BatchID.HasValue)
|
|
{
|
|
<a class="btn btn-outline-secondary" asp-action="StoryIntelligenceProgress" asp-route-batchId="@Model.BatchID">View progress</a>
|
|
}
|
|
<form asp-action="ScanManuscript" method="post">
|
|
<button class="btn btn-outline-secondary" type="submit">Scan manuscript again</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
@functions {
|
|
private static bool NeedsReview(StoryIntelligenceOnboardingChapterViewModel chapter)
|
|
=> chapter.IsFailed
|
|
|| (chapter.FailedScenes ?? 0) > 0
|
|
|| chapter.Blockers.Count > 0
|
|
|| (!chapter.CanCommit && !chapter.HasCompletedCommit && chapter.IsRunComplete);
|
|
|
|
private static string FriendlyStatus(StoryIntelligenceOnboardingChapterViewModel chapter)
|
|
{
|
|
if (chapter.HasCompletedCommit)
|
|
{
|
|
return "Scenes created";
|
|
}
|
|
|
|
if (chapter.CanCommit)
|
|
{
|
|
return chapter.Warnings.Count > 0 ? "Ready with notes" : "Ready to create";
|
|
}
|
|
|
|
return chapter.Status switch
|
|
{
|
|
StoryIntelligenceRunStatuses.Pending => "Waiting",
|
|
StoryIntelligenceRunStatuses.Running => "Reading",
|
|
StoryIntelligenceRunStatuses.Completed => "Needs attention",
|
|
StoryIntelligenceRunStatuses.CompletedWithWarnings => "Needs attention",
|
|
StoryIntelligenceRunStatuses.Failed => "Needs review",
|
|
StoryIntelligenceRunStatuses.Cancelled => "Cancelled",
|
|
_ => "Needs attention"
|
|
};
|
|
}
|
|
|
|
private static string StatusClass(StoryIntelligenceOnboardingChapterViewModel chapter)
|
|
{
|
|
if (chapter.HasCompletedCommit)
|
|
{
|
|
return "story-review-status story-review-status--created";
|
|
}
|
|
|
|
if (chapter.CanCommit)
|
|
{
|
|
return "story-review-status story-review-status--ready";
|
|
}
|
|
|
|
return chapter.IsActive
|
|
? "story-review-status story-review-status--active"
|
|
: "story-review-status story-review-status--warning";
|
|
}
|
|
}
|