@model StoryIntelligenceProgressViewModel @{ ViewData["Title"] = "Review locations"; const int previewLimit = 25; var locationCandidates = Model.LocationReview.Candidates.Take(previewLimit).ToList(); var hiddenCandidateCount = Math.Max(0, Model.LocationReview.PendingCandidateCount - locationCandidates.Count); } Story Intelligence Review Locations Review place suggestions that need a create, link, alias, or ignore decision. @if (TempData["OnboardingStoryIntelligenceError"] is string error) { @error } @if (TempData["OnboardingStoryIntelligenceMessage"] is string message) { @message } @if (Model.LocationReview.Candidates.Count == 0) { No location decisions are waiting. Locations are already up to date, or there were no location suggestions ready to import. Back to Review Centre } else { Link existing matches Expand all Collapse all @if (hiddenCandidateCount > 0) { Showing @locationCandidates.Count.ToString("N0") of @Model.LocationReview.PendingCandidateCount.ToString("N0") pending } @for (var i = 0; i < locationCandidates.Count; i++) { var candidate = locationCandidates[i]; var status = candidate.IsExistingMatch ? "existing" : "new"; var proposedParentLabel = candidate.ProposedParentLocationName ?? candidate.ParentLocationHint; var searchText = string.Join(" ", new[] { candidate.LocationName, candidate.ExistingLocationName, candidate.Category, candidate.ParentLocationHint, candidate.ProposedParentLocationName }); @candidate.LocationName @candidate.Category ยท @candidate.AppearsInScenes.ToString("N0") scene@(candidate.AppearsInScenes == 1 ? string.Empty : "s") @candidate.Confidence First appearance@Display(candidate.ExampleFirstAppearance) Proposed parent@Display(proposedParentLabel) Existing match@(candidate.ExistingLocationName ?? "None") @if (!string.IsNullOrWhiteSpace(candidate.ExampleContext)) { Scene context @candidate.ExampleContext } @if (candidate.EvidenceSummaries.Any()) { Evidence from @candidate.AppearsInScenes.ToString("N0") scene@(candidate.AppearsInScenes == 1 ? string.Empty : "s") @foreach (var evidence in candidate.EvidenceSummaries) { @evidence } } @if (candidate.IsExistingMatch) { Possible existing location @candidate.LocationName may already be @candidate.ExistingLocationName. Choose whether to link them or create a separate location. } Decision Create new location Link existing location Alias of another location Ignore Import name Parent location @if (!string.IsNullOrWhiteSpace(proposedParentLabel)) { Use proposed: @proposedParentLabel } @if (string.IsNullOrWhiteSpace(proposedParentLabel)) { Not determined } else { Not determined } @foreach (var parent in Model.LocationReview.ParentLocationOptions) { @if (candidate.ProposedParentLocationID == parent.LocationID) { @parent.DisplayName } else { @parent.DisplayName } } Alias/variant target Choose location... @foreach (var target in locationCandidates.Where(target => !string.Equals(target.Key, candidate.Key, StringComparison.OrdinalIgnoreCase))) { @target.LocationName@(target.IsExistingMatch ? $" -> {target.ExistingLocationName}" : string.Empty) } } @if (hiddenCandidateCount > 0) { Save this batch to continue with @hiddenCandidateCount.ToString("N0") more location decision@(hiddenCandidateCount == 1 ? string.Empty : "s"). } Back to Review Centre @if (Model.LocationReview.HasPreviousPage) { Previous } @if (Model.LocationReview.HasNextPage) { Next } Save location decisions } @section Scripts { } @functions { private static string Display(string? value) => string.IsNullOrWhiteSpace(value) ? "Not detected" : value; }
Story Intelligence
Review place suggestions that need a create, link, alias, or ignore decision.
Locations are already up to date, or there were no location suggestions ready to import.
@candidate.ExampleContext
@candidate.LocationName may already be @candidate.ExistingLocationName. Choose whether to link them or create a separate location.