Fix knowledge review paging actions
This commit is contained in:
parent
ba8edd26b0
commit
56236104bc
@ -1294,6 +1294,9 @@ static void StoryIntelligenceDetailedReviewsReadPersistedCandidatePages()
|
||||
var migration = File.ReadAllText(Path.Combine(root, "Sql/177_Phase27D_StoryIntelligencePersistedReviewCandidates.sql"));
|
||||
var onboarding = File.ReadAllText(Path.Combine(root, "Services/OnboardingStoryIntelligenceService.cs"));
|
||||
var program = File.ReadAllText(Path.Combine(root, "Program.cs"));
|
||||
var knowledgeView = File.ReadAllText(Path.Combine(root, "Views/Onboarding/StoryIntelligenceKnowledge.cshtml"));
|
||||
var viewModels = File.ReadAllText(Path.Combine(root, "ViewModels/OnboardingViewModels.cs"));
|
||||
var controller = File.ReadAllText(Path.Combine(root, "Controllers/OnboardingController.cs"));
|
||||
|
||||
foreach (var module in new[] { "Characters", "Locations", "Assets", "Relationships", "Knowledge" })
|
||||
{
|
||||
@ -1315,6 +1318,16 @@ static void StoryIntelligenceDetailedReviewsReadPersistedCandidatePages()
|
||||
Assert(!ExtractBetween(service, "public async Task<StoryIntelligenceRelationshipReviewViewModel> GetRelationshipReviewAsync", "public async Task<StoryIntelligenceKnowledgeReviewViewModel> GetKnowledgeReviewAsync").Contains("BuildReviewAsync", StringComparison.Ordinal), "Relationship GET must not call the old builder.");
|
||||
Assert(program.Contains("IStoryIntelligenceReviewCandidateRepository, StoryIntelligenceReviewCandidateRepository", StringComparison.Ordinal), "Persisted candidate repository should be registered.");
|
||||
Assert(program.Contains("IStoryIntelligenceReviewCandidateService, StoryIntelligenceReviewCandidateService", StringComparison.Ordinal), "Persisted candidate service should be registered.");
|
||||
Assert(knowledgeView.Contains("Page @Model.KnowledgeReview.PageNumber", StringComparison.Ordinal)
|
||||
&& knowledgeView.Contains("Showing @Model.KnowledgeReview.ShowingStart", StringComparison.Ordinal), "Knowledge review should show page and pending range counts.");
|
||||
Assert(knowledgeView.Contains("name=\"PageNumber\"", StringComparison.Ordinal), "Knowledge review should post the current page number.");
|
||||
Assert(knowledgeView.Contains("name=\"intent\" value=\"previous\"", StringComparison.Ordinal)
|
||||
&& knowledgeView.Contains("name=\"intent\" value=\"next\"", StringComparison.Ordinal), "Knowledge review Previous and Next should submit current-page decisions before navigation.");
|
||||
Assert(knowledgeView.Contains("if (Model.KnowledgeReview.HasNextPage)", StringComparison.Ordinal)
|
||||
&& knowledgeView.Contains("name=\"intent\" value=\"save\"", StringComparison.Ordinal), "Knowledge review should show Next before the last page and Save only on the last page.");
|
||||
Assert(viewModels.Contains("public int PageNumber { get; set; } = 1;", StringComparison.Ordinal), "Knowledge review posts should preserve the page being saved.");
|
||||
Assert(controller.Contains("ImportStoryIntelligenceKnowledge(StoryIntelligenceKnowledgeImportForm form, string intent = \"save\")", StringComparison.Ordinal), "Knowledge POST should accept a save/navigation intent.");
|
||||
Assert(controller.Contains("RedirectToAction(nameof(StoryIntelligenceKnowledge), new { batchId = form.BatchID, page = targetPage })", StringComparison.Ordinal), "Knowledge review should stay in-module while pending candidates remain.");
|
||||
}
|
||||
|
||||
static void StoryIntelligenceModuleCompletionLifecycleUsesPersistedCandidates()
|
||||
|
||||
@ -655,7 +655,7 @@ public sealed class OnboardingController(
|
||||
|
||||
[HttpPost("story-intelligence/knowledge")]
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> ImportStoryIntelligenceKnowledge(StoryIntelligenceKnowledgeImportForm form)
|
||||
public async Task<IActionResult> ImportStoryIntelligenceKnowledge(StoryIntelligenceKnowledgeImportForm form, string intent = "save")
|
||||
{
|
||||
var (progress, result) = await storyIntelligence.ImportKnowledgeAsync(form.BatchID, form);
|
||||
if (progress is null)
|
||||
@ -664,9 +664,26 @@ public sealed class OnboardingController(
|
||||
}
|
||||
|
||||
TempData[result.Success ? "OnboardingStoryIntelligenceMessage" : "OnboardingStoryIntelligenceError"] = result.Message;
|
||||
return result.Success
|
||||
? RedirectToAction(nameof(StoryIntelligenceReviewCentre), new { batchId = form.BatchID })
|
||||
: RedirectToAction(nameof(StoryIntelligenceKnowledge), new { batchId = form.BatchID });
|
||||
if (!result.Success)
|
||||
{
|
||||
return RedirectToAction(nameof(StoryIntelligenceKnowledge), new { batchId = form.BatchID, page = Math.Max(1, form.PageNumber) });
|
||||
}
|
||||
|
||||
var pendingCount = progress.KnowledgeReview.SummaryNeedsAttentionCount ?? progress.KnowledgeReview.PendingCandidateCount;
|
||||
if (pendingCount <= 0)
|
||||
{
|
||||
return RedirectToAction(nameof(StoryIntelligenceReviewCentre), new { batchId = form.BatchID });
|
||||
}
|
||||
|
||||
const int pageSize = 25;
|
||||
var pageCount = Math.Max(1, (int)Math.Ceiling(pendingCount / (double)pageSize));
|
||||
var currentPage = Math.Max(1, form.PageNumber);
|
||||
var targetPage = string.Equals(intent, "previous", StringComparison.OrdinalIgnoreCase)
|
||||
? currentPage - 1
|
||||
: currentPage;
|
||||
targetPage = Math.Clamp(targetPage, 1, pageCount);
|
||||
|
||||
return RedirectToAction(nameof(StoryIntelligenceKnowledge), new { batchId = form.BatchID, page = targetPage });
|
||||
}
|
||||
|
||||
[HttpGet("story-intelligence/narrative")]
|
||||
|
||||
@ -373,6 +373,9 @@ public sealed class StoryIntelligenceCharacterReviewViewModel
|
||||
public int PageSize { get; init; } = 25;
|
||||
public int TotalCandidateCount { get; init; }
|
||||
public int PendingCandidateCount { get; init; }
|
||||
public int PageCount => PendingCandidateCount <= 0 ? 1 : (int)Math.Ceiling(PendingCandidateCount / (double)PageSize);
|
||||
public int ShowingStart => PendingCandidateCount == 0 || Candidates.Count == 0 ? 0 : ((PageNumber - 1) * PageSize) + 1;
|
||||
public int ShowingEnd => ShowingStart == 0 ? 0 : Math.Min(PendingCandidateCount, ShowingStart + Candidates.Count - 1);
|
||||
public bool HasPreviousPage => PageNumber > 1;
|
||||
public bool HasNextPage => PageNumber * PageSize < PendingCandidateCount;
|
||||
public IReadOnlyList<StoryIntelligenceCharacterReviewCandidateViewModel> Candidates { get; init; } = [];
|
||||
@ -685,8 +688,11 @@ public sealed class StoryIntelligenceKnowledgeReviewViewModel
|
||||
public int PageSize { get; init; } = 25;
|
||||
public int TotalCandidateCount { get; init; }
|
||||
public int PendingCandidateCount { get; init; }
|
||||
public int PageCount => PendingCandidateCount <= 0 ? 1 : (int)Math.Ceiling(PendingCandidateCount / (double)PageSize);
|
||||
public int ShowingStart => PendingCandidateCount == 0 || Candidates.Count == 0 ? 0 : ((PageNumber - 1) * PageSize) + 1;
|
||||
public int ShowingEnd => ShowingStart == 0 ? 0 : Math.Min(PendingCandidateCount, ShowingStart + Candidates.Count - 1);
|
||||
public bool HasPreviousPage => PageNumber > 1;
|
||||
public bool HasNextPage => PageNumber * PageSize < PendingCandidateCount;
|
||||
public bool HasNextPage => PageNumber < PageCount;
|
||||
public IReadOnlyList<SelectListItem> KnowledgeStateOptions { get; init; } = [];
|
||||
public IReadOnlyList<StoryIntelligenceKnowledgeReviewCandidateViewModel> Candidates { get; init; } = [];
|
||||
}
|
||||
@ -711,6 +717,7 @@ public sealed class StoryIntelligenceKnowledgeReviewCandidateViewModel
|
||||
public sealed class StoryIntelligenceKnowledgeImportForm
|
||||
{
|
||||
public Guid BatchID { get; set; }
|
||||
public int PageNumber { get; set; } = 1;
|
||||
public List<StoryIntelligenceKnowledgeImportChoiceForm> Knowledge { get; set; } = [];
|
||||
}
|
||||
|
||||
|
||||
@ -54,6 +54,7 @@
|
||||
|
||||
<form asp-action="ImportStoryIntelligenceKnowledge" method="post" data-knowledge-review-form data-story-review-form>
|
||||
<input type="hidden" name="BatchID" value="@Model.BatchID" />
|
||||
<input type="hidden" name="PageNumber" value="@Model.KnowledgeReview.PageNumber" />
|
||||
<div class="story-character-card-grid">
|
||||
@for (var i = 0; i < knowledgeCandidates.Count; i++)
|
||||
{
|
||||
@ -147,20 +148,23 @@
|
||||
</div>
|
||||
|
||||
<div class="onboarding-actions">
|
||||
@if (hiddenCandidateCount > 0)
|
||||
{
|
||||
<span class="text-muted">Save this batch to continue with @hiddenCandidateCount.ToString("N0") more knowledge decision@(hiddenCandidateCount == 1 ? string.Empty : "s").</span>
|
||||
}
|
||||
<span class="text-muted">
|
||||
Page @Model.KnowledgeReview.PageNumber.ToString("N0") of @Model.KnowledgeReview.PageCount.ToString("N0")
|
||||
· Showing @Model.KnowledgeReview.ShowingStart.ToString("N0")-@Model.KnowledgeReview.ShowingEnd.ToString("N0") of @Model.KnowledgeReview.PendingCandidateCount.ToString("N0") pending
|
||||
</span>
|
||||
<a class="btn btn-outline-secondary" asp-action="StoryIntelligenceReviewCentre" asp-route-batchId="@Model.BatchID">Back to Review Centre</a>
|
||||
@if (Model.KnowledgeReview.HasPreviousPage)
|
||||
{
|
||||
<a class="btn btn-outline-secondary" asp-action="StoryIntelligenceKnowledge" asp-route-batchId="@Model.BatchID" asp-route-page="@(Model.KnowledgeReview.PageNumber - 1)">Previous</a>
|
||||
<button class="btn btn-outline-secondary" type="submit" name="intent" value="previous" data-busy-label="Saving page...">Previous</button>
|
||||
}
|
||||
@if (Model.KnowledgeReview.HasNextPage)
|
||||
{
|
||||
<a class="btn btn-outline-secondary" asp-action="StoryIntelligenceKnowledge" asp-route-batchId="@Model.BatchID" asp-route-page="@(Model.KnowledgeReview.PageNumber + 1)">Next</a>
|
||||
<button class="btn btn-primary" type="submit" name="intent" value="next" data-busy-label="Saving page...">Next</button>
|
||||
}
|
||||
else
|
||||
{
|
||||
<button class="btn btn-primary" type="submit" name="intent" value="save" data-busy-label="Saving knowledge...">Save knowledge decisions</button>
|
||||
}
|
||||
<button class="btn btn-primary" type="submit" data-busy-label="Saving knowledge...">Save knowledge decisions</button>
|
||||
</div>
|
||||
</form>
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user