Fix onboarding import wizard sequencing
This commit is contained in:
parent
c8148245c9
commit
24f2120cb2
@ -1589,7 +1589,12 @@ static void CoreImportWizardOrdersScenesBeforeCharacters()
|
|||||||
|
|
||||||
Assert(review.Contains("value=\"structure\"", StringComparison.Ordinal), "Chapter review should submit to structural import, not character review.");
|
Assert(review.Contains("value=\"structure\"", StringComparison.Ordinal), "Chapter review should submit to structural import, not character review.");
|
||||||
Assert(controller.Contains("var readyToImport = string.Equals(intent, \"structure\"", StringComparison.Ordinal), "Controller should treat structure intent as the scene-creation gate.");
|
Assert(controller.Contains("var readyToImport = string.Equals(intent, \"structure\"", StringComparison.Ordinal), "Controller should treat structure intent as the scene-creation gate.");
|
||||||
|
Assert(controller.Contains("Import the approved chapters and scenes before reviewing characters.", StringComparison.Ordinal), "Character review should be guarded until structural import exists.");
|
||||||
|
Assert(controller.Contains("continueToCharacters || continueCharacterReview || backCharacterReview || completeCoreImport", StringComparison.Ordinal), "Structure-save errors should remain on chapter review rather than jumping to characters.");
|
||||||
Assert(controller.Contains("FinaliseCharacterReviewAsync", StringComparison.Ordinal), "Character review should have a distinct post-structure finalisation path.");
|
Assert(controller.Contains("FinaliseCharacterReviewAsync", StringComparison.Ordinal), "Character review should have a distinct post-structure finalisation path.");
|
||||||
|
Assert(onboarding.Contains("ValidateScanStructure(review, preview);\n review = new ManuscriptScanReviewDecision", StringComparison.Ordinal), "Saving chapter review should validate only structure before scene import.");
|
||||||
|
Assert(onboarding.Contains("ValidateScanStructure(review, preview);\n\n var chapterDecisions", StringComparison.Ordinal), "Building approved structure should not validate unresolved character decisions.");
|
||||||
|
Assert(onboarding.Contains("ValidateScanReview(new ManuscriptScanReviewDecision", StringComparison.Ordinal), "Character validation should run when finalising character review.");
|
||||||
Assert(onboarding.Contains("Import the approved chapters and scenes before reviewing characters.", StringComparison.Ordinal), "Character finalisation should refuse to run before structural scenes exist.");
|
Assert(onboarding.Contains("Import the approved chapters and scenes before reviewing characters.", StringComparison.Ordinal), "Character finalisation should refuse to run before structural scenes exist.");
|
||||||
Assert(complete.Contains("Review characters", StringComparison.Ordinal), "After Word sync, the next onboarding step should be character review.");
|
Assert(complete.Contains("Review characters", StringComparison.Ordinal), "After Word sync, the next onboarding step should be character review.");
|
||||||
Assert(complete.Contains("Word may now be closed; keep this browser workflow open", StringComparison.Ordinal), "Word safe-close must be distinct from browser/core-import completion.");
|
Assert(complete.Contains("Word may now be closed; keep this browser workflow open", StringComparison.Ordinal), "Word safe-close must be distinct from browser/core-import completion.");
|
||||||
@ -1889,10 +1894,11 @@ static void OnboardingWizardKeepsCharacterPagesInsideOneMainStep()
|
|||||||
var storyService = File.ReadAllText(Path.Combine(AppContext.BaseDirectory, "../../../../PlotLine/Services/OnboardingStoryIntelligenceService.cs"));
|
var storyService = File.ReadAllText(Path.Combine(AppContext.BaseDirectory, "../../../../PlotLine/Services/OnboardingStoryIntelligenceService.cs"));
|
||||||
|
|
||||||
Assert(!header.Contains("BuildDynamicSteps", StringComparison.Ordinal), "Onboarding header should not create one top-level step per character page.");
|
Assert(!header.Contains("BuildDynamicSteps", StringComparison.Ordinal), "Onboarding header should not create one top-level step per character page.");
|
||||||
Assert(header.Contains("new(\"Review Characters\", 8)", StringComparison.Ordinal), "Onboarding header should keep character review as one main step.");
|
Assert(header.Contains("new(\"Import Scenes\", 8)", StringComparison.Ordinal), "Onboarding header should include scene import as a distinct main step.");
|
||||||
Assert(review.Contains("var currentStep = isCharacterStep ? 8 : 7;", StringComparison.Ordinal), "Scan review should keep every character page on the same main wizard step.");
|
Assert(header.Contains("new(\"Review Characters\", 9)", StringComparison.Ordinal), "Onboarding header should keep character review as one main step.");
|
||||||
|
Assert(review.Contains("var currentStep = isCharacterStep ? 9 : 7;", StringComparison.Ordinal), "Scan review should keep every character page on the same main wizard step.");
|
||||||
Assert(review.Contains("onboarding-subprogress", StringComparison.Ordinal), "Character pagination should be shown as section-level progress.");
|
Assert(review.Contains("onboarding-subprogress", StringComparison.Ordinal), "Character pagination should be shown as section-level progress.");
|
||||||
Assert(storyService.Contains("const int totalWizardSteps = 11;", StringComparison.Ordinal), "Story Intelligence summary/context should use the fixed wizard step count.");
|
Assert(storyService.Contains("const int totalWizardSteps = 12;", StringComparison.Ordinal), "Story Intelligence summary/context should use the fixed wizard step count.");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void StoryIntelligenceExperienceBootDoesNotSerialiseLiveModel()
|
static void StoryIntelligenceExperienceBootDoesNotSerialiseLiveModel()
|
||||||
|
|||||||
@ -60,6 +60,14 @@ public sealed class OnboardingController(IOnboardingService onboarding, IOnboard
|
|||||||
return RedirectToAction(nameof(Index));
|
return RedirectToAction(nameof(Index));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var build = await onboarding.GetBuildResultAsync(model.PreviewID);
|
||||||
|
if (build is null || build.SceneMappings.Count == 0)
|
||||||
|
{
|
||||||
|
TempData["ArchiveError"] = "Import the approved chapters and scenes before reviewing characters.";
|
||||||
|
await onboarding.SetCurrentStepAsync(OnboardingSteps.NextPathPreview);
|
||||||
|
return RedirectToAction(nameof(Index));
|
||||||
|
}
|
||||||
|
|
||||||
ViewData["ScanReviewStep"] = "characters";
|
ViewData["ScanReviewStep"] = "characters";
|
||||||
ViewData["CharacterReviewPage"] = Math.Max(1, page);
|
ViewData["CharacterReviewPage"] = Math.Max(1, page);
|
||||||
return View("ScanReview", model);
|
return View("ScanReview", model);
|
||||||
@ -622,6 +630,17 @@ public sealed class OnboardingController(IOnboardingService onboarding, IOnboard
|
|||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (continueToCharacters)
|
||||||
|
{
|
||||||
|
var build = await onboarding.GetBuildResultAsync(form.PreviewID);
|
||||||
|
if (build is null || build.SceneMappings.Count == 0)
|
||||||
|
{
|
||||||
|
TempData["ArchiveError"] = "Import the approved chapters and scenes before reviewing characters.";
|
||||||
|
await onboarding.SetCurrentStepAsync(OnboardingSteps.NextPathPreview);
|
||||||
|
return RedirectToAction(nameof(Index));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TempData["OnboardingReviewMessage"] = readyToImport
|
TempData["OnboardingReviewMessage"] = readyToImport
|
||||||
? "Chapter review saved. Next: import scenes and update Word."
|
? "Chapter review saved. Next: import scenes and update Word."
|
||||||
: continueToCharacters ? "Chapter and scene review saved. Next: review detected characters."
|
: continueToCharacters ? "Chapter and scene review saved. Next: review detected characters."
|
||||||
@ -642,7 +661,7 @@ public sealed class OnboardingController(IOnboardingService onboarding, IOnboard
|
|||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (readyToImport || continueCharacterReview || backCharacterReview)
|
if (continueToCharacters || continueCharacterReview || backCharacterReview || completeCoreImport)
|
||||||
{
|
{
|
||||||
ViewData["ScanReviewStep"] = "characters";
|
ViewData["ScanReviewStep"] = "characters";
|
||||||
ViewData["CharacterReviewPage"] = readyToImport
|
ViewData["CharacterReviewPage"] = readyToImport
|
||||||
|
|||||||
@ -253,7 +253,7 @@ public sealed class WordCompanionFollowHub(
|
|||||||
await Clients.Group(PresenceGroup(userId)).SendAsync("OnboardingBuildProgress", new OnboardingBuildProgress
|
await Clients.Group(PresenceGroup(userId)).SendAsync("OnboardingBuildProgress", new OnboardingBuildProgress
|
||||||
{
|
{
|
||||||
Status = "Complete",
|
Status = "Complete",
|
||||||
Message = "Manuscript structure has been created and saved. Word and this browser page may now be closed.",
|
Message = "Manuscript structure has been created and saved. Word may now be closed; keep this browser workflow open to review characters.",
|
||||||
PercentComplete = 100
|
PercentComplete = 100
|
||||||
});
|
});
|
||||||
await Clients.Group(PresenceGroup(userId)).SendAsync("OnboardingBuildMarkerSyncCompleted", new { buildId });
|
await Clients.Group(PresenceGroup(userId)).SendAsync("OnboardingBuildMarkerSyncCompleted", new { buildId });
|
||||||
|
|||||||
@ -202,7 +202,7 @@ public sealed class OnboardingService(
|
|||||||
if (readyToImport)
|
if (readyToImport)
|
||||||
{
|
{
|
||||||
await scanPreviews.SaveReviewAsync(userId, review);
|
await scanPreviews.SaveReviewAsync(userId, review);
|
||||||
ValidateScanReview(review, preview);
|
ValidateScanStructure(review, preview);
|
||||||
review = new ManuscriptScanReviewDecision
|
review = new ManuscriptScanReviewDecision
|
||||||
{
|
{
|
||||||
PreviewID = review.PreviewID,
|
PreviewID = review.PreviewID,
|
||||||
@ -236,7 +236,7 @@ public sealed class OnboardingService(
|
|||||||
}
|
}
|
||||||
|
|
||||||
await PublishBuildProgress(userId, preview.PreviewID, "Creating chapters...", 10, progress);
|
await PublishBuildProgress(userId, preview.PreviewID, "Creating chapters...", 10, progress);
|
||||||
ValidateScanReview(review, preview);
|
ValidateScanStructure(review, preview);
|
||||||
|
|
||||||
var chapterDecisions = review.Chapters.Where(chapter => chapter.Include).OrderBy(chapter => chapter.ChapterNumber).ToList();
|
var chapterDecisions = review.Chapters.Where(chapter => chapter.Include).OrderBy(chapter => chapter.ChapterNumber).ToList();
|
||||||
|
|
||||||
@ -382,6 +382,14 @@ public sealed class OnboardingService(
|
|||||||
};
|
};
|
||||||
})
|
})
|
||||||
.ToList();
|
.ToList();
|
||||||
|
ValidateScanReview(new ManuscriptScanReviewDecision
|
||||||
|
{
|
||||||
|
PreviewID = review.PreviewID,
|
||||||
|
Status = review.Status,
|
||||||
|
Chapters = review.Chapters,
|
||||||
|
Scenes = review.Scenes,
|
||||||
|
Characters = characterDecisions
|
||||||
|
}, preview);
|
||||||
|
|
||||||
var characterMappings = new List<OnboardingBuildCharacterMap>();
|
var characterMappings = new List<OnboardingBuildCharacterMap>();
|
||||||
foreach (var decision in characterDecisions.Where(IsIncludedCanonicalCharacter).OrderBy(item => item.Name).ThenBy(item => item.TemporaryCharacterKey))
|
foreach (var decision in characterDecisions.Where(IsIncludedCanonicalCharacter).OrderBy(item => item.Name).ThenBy(item => item.TemporaryCharacterKey))
|
||||||
|
|||||||
@ -71,9 +71,9 @@ public sealed class OnboardingStoryIntelligenceService(
|
|||||||
var included = IncludedChapters(preview, review);
|
var included = IncludedChapters(preview, review);
|
||||||
var existingBatch = await batchStore.GetLatestForPreviewAsync(userId, preview.PreviewID);
|
var existingBatch = await batchStore.GetLatestForPreviewAsync(userId, preview.PreviewID);
|
||||||
var missingTextCount = included.Count(chapter => string.IsNullOrWhiteSpace(chapter.Preview.ChapterText));
|
var missingTextCount = included.Count(chapter => string.IsNullOrWhiteSpace(chapter.Preview.ChapterText));
|
||||||
const int storySummaryStep = 9;
|
const int storySummaryStep = 10;
|
||||||
const int storyContextStep = 10;
|
const int storyContextStep = 11;
|
||||||
const int totalWizardSteps = 11;
|
const int totalWizardSteps = 12;
|
||||||
return new StoryIntelligenceOverviewViewModel
|
return new StoryIntelligenceOverviewViewModel
|
||||||
{
|
{
|
||||||
PreviewID = preview.PreviewID,
|
PreviewID = preview.PreviewID,
|
||||||
|
|||||||
@ -127,9 +127,9 @@ public sealed class StoryIntelligenceOverviewViewModel
|
|||||||
public int ApprovedChapterCount { get; init; }
|
public int ApprovedChapterCount { get; init; }
|
||||||
public int ApprovedWordCount { get; init; }
|
public int ApprovedWordCount { get; init; }
|
||||||
public int MissingChapterTextCount { get; init; }
|
public int MissingChapterTextCount { get; init; }
|
||||||
public int WizardCurrentStep { get; init; } = 9;
|
public int WizardCurrentStep { get; init; } = 10;
|
||||||
public int WizardContextStep { get; init; } = 10;
|
public int WizardContextStep { get; init; } = 11;
|
||||||
public int WizardTotalSteps { get; init; } = 10;
|
public int WizardTotalSteps { get; init; } = 12;
|
||||||
public string? Message { get; init; }
|
public string? Message { get; init; }
|
||||||
public Guid? ExistingBatchID { get; init; }
|
public Guid? ExistingBatchID { get; init; }
|
||||||
public StoryIntelligenceJobProgress? ExistingJob { get; init; }
|
public StoryIntelligenceJobProgress? ExistingJob { get; init; }
|
||||||
|
|||||||
@ -6,15 +6,7 @@
|
|||||||
|
|
||||||
<section class="onboarding-shell" aria-labelledby="build-complete-title">
|
<section class="onboarding-shell" aria-labelledby="build-complete-title">
|
||||||
<div class="onboarding-panel onboarding-review-panel">
|
<div class="onboarding-panel onboarding-review-panel">
|
||||||
<ol class="onboarding-stepper onboarding-stepper--complete" aria-label="Story setup journey">
|
<partial name="_OnboardingJourneyHeader" model="@(new OnboardingJourneyHeaderViewModel { CurrentStep = coreComplete ? 12 : 9, TotalSteps = 12 })" />
|
||||||
@foreach (var label in new[] { "Welcome", "Writing Preferences", "Project", "Book", "Connect Word", "Scan", "Review", "Create Structure", "Complete" })
|
|
||||||
{
|
|
||||||
<li class="is-complete">
|
|
||||||
<span></span>
|
|
||||||
<strong>@label</strong>
|
|
||||||
</li>
|
|
||||||
}
|
|
||||||
</ol>
|
|
||||||
<div class="onboarding-copy">
|
<div class="onboarding-copy">
|
||||||
<p class="eyebrow">Core Import Complete</p>
|
<p class="eyebrow">Core Import Complete</p>
|
||||||
<div class="onboarding-success-heading">
|
<div class="onboarding-success-heading">
|
||||||
|
|||||||
@ -3,11 +3,21 @@
|
|||||||
@{
|
@{
|
||||||
ViewData["Title"] = "Set up PlotDirector";
|
ViewData["Title"] = "Set up PlotDirector";
|
||||||
var currentJourneyOrder = CurrentJourneyOrder(Model);
|
var currentJourneyOrder = CurrentJourneyOrder(Model);
|
||||||
|
var structureReadyToImport = string.Equals(Model.ScanState.ReviewStatus, ManuscriptScanReviewStatuses.ReadyToImport, StringComparison.Ordinal);
|
||||||
|
var reviewedScanAvailable = Model.ScanState.IsComplete || structureReadyToImport;
|
||||||
}
|
}
|
||||||
|
|
||||||
<section class="onboarding-shell" aria-labelledby="onboarding-title">
|
<section class="onboarding-shell" aria-labelledby="onboarding-title">
|
||||||
<div class="onboarding-panel">
|
<div class="onboarding-panel">
|
||||||
<partial name="_OnboardingJourneyHeader" model="@(new OnboardingJourneyHeaderViewModel { CurrentStep = currentJourneyOrder })" />
|
<partial name="_OnboardingJourneyHeader" model="@(new OnboardingJourneyHeaderViewModel { CurrentStep = currentJourneyOrder })" />
|
||||||
|
@if (TempData["OnboardingReviewMessage"] is string reviewMessage)
|
||||||
|
{
|
||||||
|
<div class="alert alert-success">@reviewMessage</div>
|
||||||
|
}
|
||||||
|
@if (TempData["ArchiveError"] is string archiveError)
|
||||||
|
{
|
||||||
|
<div class="alert alert-danger">@archiveError</div>
|
||||||
|
}
|
||||||
|
|
||||||
@if (Model.CurrentStep == OnboardingSteps.Welcome)
|
@if (Model.CurrentStep == OnboardingSteps.Welcome)
|
||||||
{
|
{
|
||||||
@ -229,11 +239,11 @@
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
<div class="onboarding-copy">
|
<div class="onboarding-copy">
|
||||||
<p class="eyebrow">Step @currentJourneyOrder of 10</p>
|
<p class="eyebrow">Step @currentJourneyOrder of 12</p>
|
||||||
@if (Model.IsMicrosoftWordPath)
|
@if (Model.IsMicrosoftWordPath)
|
||||||
{
|
{
|
||||||
<h1 id="onboarding-title">@(currentJourneyOrder >= 6 ? "Scan Manuscript" : "Connect your Word Companion")</h1>
|
<h1 id="onboarding-title">@(structureReadyToImport ? "Import scenes and Word markers" : currentJourneyOrder >= 6 ? "Scan Manuscript" : "Connect your Word Companion")</h1>
|
||||||
<p>Open your manuscript in Word and start the Companion. When it is connected, use the wizard button below to scan and continue.</p>
|
<p>@(structureReadyToImport ? "Keep Word and this browser page open while PlotDirector detects scene boundaries, creates the manuscript structure, inserts bookmark IDs, and saves the document." : "Open your manuscript in Word and start the Companion. When it is connected, use the wizard button below to scan and continue.")</p>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -314,10 +324,17 @@
|
|||||||
</section>
|
</section>
|
||||||
}
|
}
|
||||||
<div class="onboarding-actions">
|
<div class="onboarding-actions">
|
||||||
|
@if (Model.IsMicrosoftWordPath && reviewedScanAvailable && Model.ScanState.PreviewID.HasValue)
|
||||||
|
{
|
||||||
|
<a class="btn btn-outline-secondary" asp-controller="Onboarding" asp-action="ScanReview" asp-route-previewId="@Model.ScanState.PreviewID">Back to chapter review</a>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
<form asp-controller="Onboarding" asp-action="Back" method="post">
|
<form asp-controller="Onboarding" asp-action="Back" method="post">
|
||||||
<button class="btn btn-outline-secondary" type="submit" name="currentStep" value="@OnboardingSteps.NextPathPreview">Back</button>
|
<button class="btn btn-outline-secondary" type="submit" name="currentStep" value="@OnboardingSteps.NextPathPreview">Back</button>
|
||||||
</form>
|
</form>
|
||||||
@if (Model.IsMicrosoftWordPath && string.Equals(Model.ScanState.ReviewStatus, ManuscriptScanReviewStatuses.ReadyToImport, StringComparison.Ordinal))
|
}
|
||||||
|
@if (Model.IsMicrosoftWordPath && structureReadyToImport)
|
||||||
{
|
{
|
||||||
<button class="btn btn-primary"
|
<button class="btn btn-primary"
|
||||||
type="button"
|
type="button"
|
||||||
@ -444,13 +461,13 @@
|
|||||||
OnboardingSteps.WritingSoftware => 3,
|
OnboardingSteps.WritingSoftware => 3,
|
||||||
OnboardingSteps.Project => 4,
|
OnboardingSteps.Project => 4,
|
||||||
OnboardingSteps.Book => 5,
|
OnboardingSteps.Book => 5,
|
||||||
OnboardingSteps.NextPathPreview when !model.IsMicrosoftWordPath => 10,
|
OnboardingSteps.NextPathPreview when !model.IsMicrosoftWordPath => 11,
|
||||||
OnboardingSteps.NextPathPreview when string.Equals(model.ScanState.ReviewStatus, ManuscriptScanReviewStatuses.ReadyToImport, StringComparison.Ordinal) => 9,
|
OnboardingSteps.NextPathPreview when string.Equals(model.ScanState.ReviewStatus, ManuscriptScanReviewStatuses.ReadyToImport, StringComparison.Ordinal) => 8,
|
||||||
OnboardingSteps.NextPathPreview when model.ScanState.IsComplete => 7,
|
OnboardingSteps.NextPathPreview when model.ScanState.IsComplete => 7,
|
||||||
OnboardingSteps.NextPathPreview when model.ScanState.IsRunning || model.ScanState.IsFailed || model.ScanState.PercentComplete.HasValue => 6,
|
OnboardingSteps.NextPathPreview when model.ScanState.IsRunning || model.ScanState.IsFailed || model.ScanState.PercentComplete.HasValue => 6,
|
||||||
OnboardingSteps.NextPathPreview when model.CompanionPresence.IsConnected => 6,
|
OnboardingSteps.NextPathPreview when model.CompanionPresence.IsConnected => 6,
|
||||||
OnboardingSteps.NextPathPreview => 6,
|
OnboardingSteps.NextPathPreview => 6,
|
||||||
OnboardingSteps.Complete => 10,
|
OnboardingSteps.Complete => 12,
|
||||||
_ => 1
|
_ => 1
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,8 +31,8 @@
|
|||||||
var requestedCharacterPage = ViewData["CharacterReviewPage"] is int requestedPage ? requestedPage : 1;
|
var requestedCharacterPage = ViewData["CharacterReviewPage"] is int requestedPage ? requestedPage : 1;
|
||||||
var characterPage = Math.Clamp(requestedCharacterPage, 1, characterReviewPageCount);
|
var characterPage = Math.Clamp(requestedCharacterPage, 1, characterReviewPageCount);
|
||||||
var currentCharacters = primaryCharacters.Skip((characterPage - 1) * characterPageSize).Take(characterPageSize).ToList();
|
var currentCharacters = primaryCharacters.Skip((characterPage - 1) * characterPageSize).Take(characterPageSize).ToList();
|
||||||
var currentStep = isCharacterStep ? 8 : 7;
|
var currentStep = isCharacterStep ? 9 : 7;
|
||||||
const int totalSteps = 11;
|
const int totalSteps = 12;
|
||||||
var characterPageTitle = $"Review Characters {characterPage} of {primaryCharacterPageCount}";
|
var characterPageTitle = $"Review Characters {characterPage} of {primaryCharacterPageCount}";
|
||||||
var duplicateCanonicalNames = primaryCharacters
|
var duplicateCanonicalNames = primaryCharacters
|
||||||
.Where(candidate => candidate.Include && string.IsNullOrWhiteSpace(candidate.AliasTargetTemporaryCharacterKey))
|
.Where(candidate => candidate.Include && string.IsNullOrWhiteSpace(candidate.AliasTargetTemporaryCharacterKey))
|
||||||
@ -67,7 +67,7 @@
|
|||||||
<div class="onboarding-copy">
|
<div class="onboarding-copy">
|
||||||
<p class="eyebrow">Step @currentStep of @totalSteps</p>
|
<p class="eyebrow">Step @currentStep of @totalSteps</p>
|
||||||
<h1 id="scan-review-title">@(isCharacterStep ? "Review Characters" : "Review Chapters")</h1>
|
<h1 id="scan-review-title">@(isCharacterStep ? "Review Characters" : "Review Chapters")</h1>
|
||||||
<p>@(isCharacterStep ? "Review this page of detected names and aliases, then continue through the character section." : "Confirm the chapter and scene structure before reviewing detected characters.")</p>
|
<p>@(isCharacterStep ? "Review this page of detected names and aliases, then continue through the character section." : "Confirm the chapter structure before PlotDirector detects scenes with AI and updates Word markers.")</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@if (TempData["OnboardingReviewMessage"] is string reviewMessage)
|
@if (TempData["OnboardingReviewMessage"] is string reviewMessage)
|
||||||
@ -192,7 +192,7 @@
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
<div class="onboarding-actions onboarding-actions--inline">
|
<div class="onboarding-actions onboarding-actions--inline">
|
||||||
<button class="btn btn-primary" type="submit" name="intent" value="structure">Save chapters and import scenes</button>
|
<button class="btn btn-primary" type="submit" name="intent" value="structure">Save chapter review</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -364,7 +364,7 @@
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
<a class="btn btn-outline-secondary" asp-controller="Onboarding" asp-action="Index">Back to setup</a>
|
<a class="btn btn-outline-secondary" asp-controller="Onboarding" asp-action="Index">Back to setup</a>
|
||||||
<button class="btn btn-primary" type="submit" name="intent" value="structure">Save chapters and import scenes</button>
|
<button class="btn btn-primary" type="submit" name="intent" value="structure">Save chapter review</button>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@ -36,10 +36,11 @@
|
|||||||
new("Book", 5),
|
new("Book", 5),
|
||||||
new("Connect Word", 6),
|
new("Connect Word", 6),
|
||||||
new("Review Chapters", 7),
|
new("Review Chapters", 7),
|
||||||
new("Review Characters", 8),
|
new("Import Scenes", 8),
|
||||||
new("Story Summary", 9),
|
new("Review Characters", 9),
|
||||||
new("Story Context", 10),
|
new("Story Summary", 10),
|
||||||
new("Complete", 11)
|
new("Story Context", 11),
|
||||||
|
new("Complete", 12)
|
||||||
];
|
];
|
||||||
|
|
||||||
private static string StepClass(int order, int currentStep)
|
private static string StepClass(int order, int currentStep)
|
||||||
|
|||||||
@ -220,6 +220,7 @@
|
|||||||
if (!previewId) {
|
if (!previewId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
pendingBuildPreviewId = previewId;
|
||||||
button.disabled = true;
|
button.disabled = true;
|
||||||
document.querySelectorAll("[data-onboarding-build-panel]").forEach((node) => {
|
document.querySelectorAll("[data-onboarding-build-panel]").forEach((node) => {
|
||||||
node.classList.add("is-running");
|
node.classList.add("is-running");
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user