Phase 12J: Warning Investigation Workflow Improvements.
This commit is contained in:
parent
6a2aeeea90
commit
ecc8d3c76a
@ -8,8 +8,15 @@ namespace PlotLine.Controllers;
|
||||
[Authorize]
|
||||
public sealed class ContinuityExplorerController(IStoryStateService storyState) : Controller
|
||||
{
|
||||
public async Task<IActionResult> Index([FromQuery] ContinuityFilter filter)
|
||||
public async Task<IActionResult> Index(
|
||||
[FromQuery] ContinuityFilter filter,
|
||||
[FromQuery] string? mode,
|
||||
[FromQuery] int? characterId,
|
||||
[FromQuery] int? assetId,
|
||||
[FromQuery] int? locationId,
|
||||
[FromQuery] int? sceneId)
|
||||
{
|
||||
ApplyDeepLinkAliases(filter, mode, characterId, assetId, locationId, sceneId);
|
||||
if (filter.ProjectID == 0)
|
||||
{
|
||||
return BadRequest("ProjectID is required.");
|
||||
@ -25,4 +32,55 @@ public sealed class ContinuityExplorerController(IStoryStateService storyState)
|
||||
{
|
||||
return RedirectToAction(nameof(Index), filter);
|
||||
}
|
||||
|
||||
private static void ApplyDeepLinkAliases(ContinuityFilter filter, string? mode, int? characterId, int? assetId, int? locationId, int? sceneId)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(mode))
|
||||
{
|
||||
filter.DisplayMode = mode;
|
||||
}
|
||||
|
||||
var hasFriendlyEntityFilter = characterId.HasValue || assetId.HasValue || locationId.HasValue;
|
||||
if (hasFriendlyEntityFilter)
|
||||
{
|
||||
filter.EntityTypes = [];
|
||||
if (characterId.HasValue)
|
||||
{
|
||||
filter.EntityTypes.Add("Characters");
|
||||
}
|
||||
|
||||
if (assetId.HasValue)
|
||||
{
|
||||
filter.EntityTypes.Add("Assets");
|
||||
}
|
||||
|
||||
if (locationId.HasValue || string.Equals(filter.DisplayMode, "LocationActivity", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
filter.EntityTypes.Add("Locations");
|
||||
}
|
||||
}
|
||||
|
||||
if (characterId.HasValue && !filter.CharacterIDs.Contains(characterId.Value))
|
||||
{
|
||||
filter.CharacterIDs.Add(characterId.Value);
|
||||
}
|
||||
|
||||
if (assetId.HasValue && !filter.AssetIDs.Contains(assetId.Value))
|
||||
{
|
||||
filter.AssetIDs.Add(assetId.Value);
|
||||
}
|
||||
|
||||
if (locationId.HasValue && !filter.LocationIDs.Contains(locationId.Value))
|
||||
{
|
||||
filter.LocationIDs.Add(locationId.Value);
|
||||
}
|
||||
|
||||
if (sceneId.HasValue && !filter.StartSceneID.HasValue && !filter.EndSceneID.HasValue && !filter.SelectedSceneID.HasValue)
|
||||
{
|
||||
filter.SceneRangeMode = "Custom";
|
||||
filter.StartSceneID = sceneId.Value;
|
||||
filter.EndSceneID = sceneId.Value;
|
||||
filter.SelectedSceneID = sceneId.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3029,11 +3029,17 @@ public sealed class StoryStateService(
|
||||
warning.KnowledgeDescription = knowledgeDescription;
|
||||
warning.PreviousKnowledgeState = previous.Item.KnowledgeStateName;
|
||||
warning.CurrentKnowledgeState = current.Item.KnowledgeStateName;
|
||||
var previousSceneContext = context.SceneContexts.GetValueOrDefault(previous.Item.SceneID);
|
||||
var currentSceneContext = context.SceneContexts.GetValueOrDefault(current.Item.SceneID);
|
||||
warning.PreviousBookId = previousSceneContext?.BookID;
|
||||
warning.PreviousChapterId = previousSceneContext?.ChapterID;
|
||||
warning.PreviousSceneId = previous.Item.SceneID;
|
||||
warning.PreviousSceneDisplayName = context.SceneContexts.GetValueOrDefault(previous.Item.SceneID)?.SceneDisplayName
|
||||
warning.PreviousSceneDisplayName = previousSceneContext?.SceneDisplayName
|
||||
?? context.SceneLabels.GetValueOrDefault(previous.Item.SceneID, SceneLabel(previous.Item.SceneNumber, previous.Item.SceneTitle));
|
||||
warning.CurrentBookId = currentSceneContext?.BookID;
|
||||
warning.CurrentChapterId = currentSceneContext?.ChapterID;
|
||||
warning.CurrentSceneId = current.Item.SceneID;
|
||||
warning.CurrentSceneDisplayName = context.SceneContexts.GetValueOrDefault(current.Item.SceneID)?.SceneDisplayName
|
||||
warning.CurrentSceneDisplayName = currentSceneContext?.SceneDisplayName
|
||||
?? context.SceneLabels.GetValueOrDefault(current.Item.SceneID, SceneLabel(current.Item.SceneNumber, current.Item.SceneTitle));
|
||||
warnings.Add(warning);
|
||||
}
|
||||
@ -3218,6 +3224,8 @@ public sealed class StoryStateService(
|
||||
Message = message,
|
||||
CharacterID = characterId,
|
||||
AssetID = assetId,
|
||||
BookID = sceneContext?.BookID,
|
||||
ChapterID = sceneContext?.ChapterID,
|
||||
SceneID = sceneId,
|
||||
SceneDisplayName = sceneContext?.SceneDisplayName ?? (sceneId.HasValue ? context.SceneLabels.GetValueOrDefault(sceneId.Value, string.Empty) : string.Empty),
|
||||
BookDisplayName = sceneContext?.BookDisplayName ?? string.Empty,
|
||||
@ -4008,7 +4016,10 @@ public sealed class ContinuityValidationService(
|
||||
.Where(x => !chapterId.HasValue || x.ChapterID == chapterId.Value)
|
||||
.ToList();
|
||||
var continuityWarnings = await storyState.GetContinuityWarningsAsync(projectId, BuildWarningContinuityFilter(projectId, bookId, chapterId, sceneId));
|
||||
var dashboardWarnings = rows.Select(ToProjectWarning).Concat(continuityWarnings.Select(ToProjectWarning)).ToList();
|
||||
var booksById = projectBooks.ToDictionary(x => x.BookID);
|
||||
var chaptersById = projectChapters.ToDictionary(x => x.ChapterID);
|
||||
var dashboardWarnings = rows.Select(x => ToProjectWarning(x, booksById, chaptersById)).Concat(continuityWarnings.Select(ToProjectWarning)).ToList();
|
||||
ApplyWarningDisplayContext(dashboardWarnings, bookId, chapterId, booksById, chaptersById);
|
||||
var availableWarnings = dashboardWarnings.ToList();
|
||||
var hasAnyWarnings = availableWarnings.Any();
|
||||
|
||||
@ -4083,8 +4094,20 @@ public sealed class ContinuityValidationService(
|
||||
return filter;
|
||||
}
|
||||
|
||||
private static ProjectWarningViewModel ToProjectWarning(ContinuityWarning warning)
|
||||
private static ProjectWarningViewModel ToProjectWarning(
|
||||
ContinuityWarning warning,
|
||||
IReadOnlyDictionary<int, Book> booksById,
|
||||
IReadOnlyDictionary<int, Chapter> chaptersById)
|
||||
{
|
||||
var bookDisplayName = warning.BookID.HasValue && booksById.TryGetValue(warning.BookID.Value, out var book)
|
||||
? $"Book {book.BookNumber:g}: {book.BookTitle}"
|
||||
: warning.BookTitle ?? string.Empty;
|
||||
var chapterDisplayName = warning.ChapterID.HasValue && chaptersById.TryGetValue(warning.ChapterID.Value, out var chapter)
|
||||
? $"Chapter {chapter.ChapterNumber:g}: {chapter.ChapterTitle}"
|
||||
: warning.ChapterNumber.HasValue
|
||||
? $"Chapter {warning.ChapterNumber:g}: {warning.ChapterTitle}"
|
||||
: string.Empty;
|
||||
|
||||
return new ProjectWarningViewModel
|
||||
{
|
||||
Source = "Persisted",
|
||||
@ -4096,11 +4119,9 @@ public sealed class ContinuityValidationService(
|
||||
Message = warning.Message,
|
||||
Details = warning.Details,
|
||||
BookID = warning.BookID,
|
||||
BookDisplayName = string.IsNullOrWhiteSpace(warning.BookTitle) ? string.Empty : warning.BookTitle,
|
||||
BookDisplayName = bookDisplayName,
|
||||
ChapterID = warning.ChapterID,
|
||||
ChapterDisplayName = warning.ChapterNumber.HasValue
|
||||
? $"Ch {warning.ChapterNumber:g}: {warning.ChapterTitle}"
|
||||
: string.Empty,
|
||||
ChapterDisplayName = chapterDisplayName,
|
||||
SceneID = warning.SceneID,
|
||||
SceneDisplayName = warning.SceneID.HasValue
|
||||
? SceneLabel(warning.SceneNumber ?? 0, warning.SceneTitle ?? string.Empty)
|
||||
@ -4122,7 +4143,9 @@ public sealed class ContinuityValidationService(
|
||||
Category = WarningCategoryForGenerated(warning),
|
||||
Severity = warning.Severity,
|
||||
Message = warning.Message,
|
||||
BookID = warning.BookID,
|
||||
BookDisplayName = warning.BookDisplayName,
|
||||
ChapterID = warning.ChapterID,
|
||||
ChapterDisplayName = warning.ChapterDisplayName,
|
||||
SceneID = warning.SceneID,
|
||||
SceneDisplayName = warning.SceneDisplayName,
|
||||
@ -4138,10 +4161,16 @@ public sealed class ContinuityValidationService(
|
||||
KnowledgeDescription = warning.KnowledgeDescription,
|
||||
PreviousKnowledgeState = warning.PreviousKnowledgeState,
|
||||
CurrentKnowledgeState = warning.CurrentKnowledgeState,
|
||||
PreviousBookId = warning.PreviousBookId,
|
||||
PreviousChapterId = warning.PreviousChapterId,
|
||||
PreviousSceneId = warning.PreviousSceneId,
|
||||
PreviousSceneDisplayName = warning.PreviousSceneDisplayName,
|
||||
PreviousContextSceneDisplayName = warning.PreviousContextSceneDisplayName,
|
||||
CurrentBookId = warning.CurrentBookId,
|
||||
CurrentChapterId = warning.CurrentChapterId,
|
||||
CurrentSceneId = warning.CurrentSceneId,
|
||||
CurrentSceneDisplayName = warning.CurrentSceneDisplayName,
|
||||
CurrentContextSceneDisplayName = warning.CurrentContextSceneDisplayName,
|
||||
EstablishedSceneId = warning.EstablishedSceneId,
|
||||
EstablishedSceneDisplayName = warning.EstablishedSceneDisplayName,
|
||||
ReferencedSceneId = warning.ReferencedSceneId,
|
||||
@ -4150,6 +4179,124 @@ public sealed class ContinuityValidationService(
|
||||
};
|
||||
}
|
||||
|
||||
private static void ApplyWarningDisplayContext(
|
||||
List<ProjectWarningViewModel> warnings,
|
||||
int? scopedBookId,
|
||||
int? scopedChapterId,
|
||||
IReadOnlyDictionary<int, Book> booksById,
|
||||
IReadOnlyDictionary<int, Chapter> chaptersById)
|
||||
{
|
||||
foreach (var warning in warnings)
|
||||
{
|
||||
warning.ContextSceneDisplayName = FormatWarningSceneContext(
|
||||
warning.BookID,
|
||||
warning.BookDisplayName,
|
||||
warning.ChapterID,
|
||||
warning.ChapterDisplayName,
|
||||
warning.SceneDisplayName,
|
||||
scopedBookId,
|
||||
scopedChapterId,
|
||||
booksById,
|
||||
chaptersById);
|
||||
warning.PreviousContextSceneDisplayName = FormatWarningSceneContext(
|
||||
warning.PreviousBookId,
|
||||
string.Empty,
|
||||
warning.PreviousChapterId,
|
||||
string.Empty,
|
||||
warning.PreviousSceneDisplayName,
|
||||
scopedBookId,
|
||||
scopedChapterId,
|
||||
booksById,
|
||||
chaptersById);
|
||||
warning.CurrentContextSceneDisplayName = FormatWarningSceneContext(
|
||||
warning.CurrentBookId,
|
||||
string.Empty,
|
||||
warning.CurrentChapterId,
|
||||
string.Empty,
|
||||
warning.CurrentSceneDisplayName,
|
||||
scopedBookId,
|
||||
scopedChapterId,
|
||||
booksById,
|
||||
chaptersById);
|
||||
warning.EstablishedContextSceneDisplayName = string.IsNullOrWhiteSpace(warning.EstablishedSceneDisplayName)
|
||||
? string.Empty
|
||||
: warning.EstablishedSceneDisplayName;
|
||||
warning.ReferencedContextSceneDisplayName = string.IsNullOrWhiteSpace(warning.ReferencedSceneDisplayName)
|
||||
? string.Empty
|
||||
: warning.ReferencedSceneDisplayName;
|
||||
ApplyInvestigationTarget(warning);
|
||||
}
|
||||
}
|
||||
|
||||
private static string FormatWarningSceneContext(
|
||||
int? bookId,
|
||||
string bookDisplayName,
|
||||
int? chapterId,
|
||||
string chapterDisplayName,
|
||||
string sceneDisplayName,
|
||||
int? scopedBookId,
|
||||
int? scopedChapterId,
|
||||
IReadOnlyDictionary<int, Book> booksById,
|
||||
IReadOnlyDictionary<int, Chapter> chaptersById)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(sceneDisplayName))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(bookDisplayName) && bookId.HasValue && booksById.TryGetValue(bookId.Value, out var book))
|
||||
{
|
||||
bookDisplayName = $"Book {book.BookNumber:g}: {book.BookTitle}";
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(chapterDisplayName) && chapterId.HasValue && chaptersById.TryGetValue(chapterId.Value, out var chapter))
|
||||
{
|
||||
chapterDisplayName = $"Chapter {chapter.ChapterNumber:g}: {chapter.ChapterTitle}";
|
||||
}
|
||||
|
||||
if (scopedChapterId.HasValue)
|
||||
{
|
||||
return sceneDisplayName;
|
||||
}
|
||||
|
||||
if (scopedBookId.HasValue || (bookId.HasValue && scopedBookId == bookId))
|
||||
{
|
||||
return string.IsNullOrWhiteSpace(chapterDisplayName)
|
||||
? sceneDisplayName
|
||||
: $"{chapterDisplayName} • {sceneDisplayName}";
|
||||
}
|
||||
|
||||
var parts = new List<string>();
|
||||
if (!string.IsNullOrWhiteSpace(bookDisplayName))
|
||||
{
|
||||
parts.Add(bookDisplayName);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(chapterDisplayName))
|
||||
{
|
||||
parts.Add(chapterDisplayName);
|
||||
}
|
||||
|
||||
parts.Add(sceneDisplayName);
|
||||
return string.Join(" • ", parts);
|
||||
}
|
||||
|
||||
private static void ApplyInvestigationTarget(ProjectWarningViewModel warning)
|
||||
{
|
||||
if (warning.Source != "Generated")
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
warning.CanInvestigate = true;
|
||||
warning.InvestigationDisplayMode = warning.WarningTypeDisplayName switch
|
||||
{
|
||||
"Multiple Character Locations" => "LocationActivity",
|
||||
_ => "Journey"
|
||||
};
|
||||
warning.InvestigationSceneId = warning.CurrentSceneId ?? warning.ReferencedSceneId ?? warning.SceneID;
|
||||
}
|
||||
|
||||
private static string WarningCategoryForPersisted(ContinuityWarning warning)
|
||||
{
|
||||
return warning.EntityType switch
|
||||
|
||||
@ -325,8 +325,11 @@ public sealed class ContinuityWarningViewModel
|
||||
public int? CharacterID { get; set; }
|
||||
public string CharacterName { get; set; } = string.Empty;
|
||||
public int? AssetID { get; set; }
|
||||
public int? BookID { get; set; }
|
||||
public int? ChapterID { get; set; }
|
||||
public int? SceneID { get; set; }
|
||||
public string SceneDisplayName { get; set; } = string.Empty;
|
||||
public string ContextSceneDisplayName { get; set; } = string.Empty;
|
||||
public string BookDisplayName { get; set; } = string.Empty;
|
||||
public string ChapterDisplayName { get; set; } = string.Empty;
|
||||
public bool IsAcknowledged { get; set; }
|
||||
@ -336,14 +339,25 @@ public sealed class ContinuityWarningViewModel
|
||||
public string KnowledgeDescription { get; set; } = string.Empty;
|
||||
public string PreviousKnowledgeState { get; set; } = string.Empty;
|
||||
public string CurrentKnowledgeState { get; set; } = string.Empty;
|
||||
public int? PreviousBookId { get; set; }
|
||||
public int? PreviousChapterId { get; set; }
|
||||
public int? PreviousSceneId { get; set; }
|
||||
public string PreviousSceneDisplayName { get; set; } = string.Empty;
|
||||
public string PreviousContextSceneDisplayName { get; set; } = string.Empty;
|
||||
public int? CurrentBookId { get; set; }
|
||||
public int? CurrentChapterId { get; set; }
|
||||
public int? CurrentSceneId { get; set; }
|
||||
public string CurrentSceneDisplayName { get; set; } = string.Empty;
|
||||
public string CurrentContextSceneDisplayName { get; set; } = string.Empty;
|
||||
public int? EstablishedSceneId { get; set; }
|
||||
public string EstablishedSceneDisplayName { get; set; } = string.Empty;
|
||||
public string EstablishedContextSceneDisplayName { get; set; } = string.Empty;
|
||||
public int? ReferencedSceneId { get; set; }
|
||||
public string ReferencedSceneDisplayName { get; set; } = string.Empty;
|
||||
public string ReferencedContextSceneDisplayName { get; set; } = string.Empty;
|
||||
public string InvestigationDisplayMode { get; set; } = string.Empty;
|
||||
public int? InvestigationSceneId { get; set; }
|
||||
public bool CanInvestigate { get; set; }
|
||||
}
|
||||
|
||||
public sealed class CharacterJourneyViewModel
|
||||
@ -1685,6 +1699,7 @@ public sealed class ProjectWarningViewModel
|
||||
public string ChapterDisplayName { get; set; } = string.Empty;
|
||||
public int? SceneID { get; set; }
|
||||
public string SceneDisplayName { get; set; } = string.Empty;
|
||||
public string ContextSceneDisplayName { get; set; } = string.Empty;
|
||||
public int? CharacterID { get; set; }
|
||||
public string CharacterName { get; set; } = string.Empty;
|
||||
public int? AssetID { get; set; }
|
||||
@ -1699,14 +1714,25 @@ public sealed class ProjectWarningViewModel
|
||||
public string KnowledgeDescription { get; set; } = string.Empty;
|
||||
public string PreviousKnowledgeState { get; set; } = string.Empty;
|
||||
public string CurrentKnowledgeState { get; set; } = string.Empty;
|
||||
public int? PreviousBookId { get; set; }
|
||||
public int? PreviousChapterId { get; set; }
|
||||
public int? PreviousSceneId { get; set; }
|
||||
public string PreviousSceneDisplayName { get; set; } = string.Empty;
|
||||
public string PreviousContextSceneDisplayName { get; set; } = string.Empty;
|
||||
public int? CurrentBookId { get; set; }
|
||||
public int? CurrentChapterId { get; set; }
|
||||
public int? CurrentSceneId { get; set; }
|
||||
public string CurrentSceneDisplayName { get; set; } = string.Empty;
|
||||
public string CurrentContextSceneDisplayName { get; set; } = string.Empty;
|
||||
public int? EstablishedSceneId { get; set; }
|
||||
public string EstablishedSceneDisplayName { get; set; } = string.Empty;
|
||||
public string EstablishedContextSceneDisplayName { get; set; } = string.Empty;
|
||||
public int? ReferencedSceneId { get; set; }
|
||||
public string ReferencedSceneDisplayName { get; set; } = string.Empty;
|
||||
public string ReferencedContextSceneDisplayName { get; set; } = string.Empty;
|
||||
public string InvestigationDisplayMode { get; set; } = string.Empty;
|
||||
public int? InvestigationSceneId { get; set; }
|
||||
public bool CanInvestigate { get; set; }
|
||||
public DateTime LastDetectedDate { get; set; }
|
||||
}
|
||||
|
||||
|
||||
@ -183,28 +183,28 @@
|
||||
{
|
||||
<small class="text-muted d-block">
|
||||
Previous:
|
||||
<a asp-controller="Timeline" asp-action="Index" asp-route-projectId="@Model.Project.ProjectID" asp-route-selectedSceneId="@warning.PreviousSceneId">@warning.PreviousSceneDisplayName</a>
|
||||
<a asp-controller="Timeline" asp-action="Index" asp-route-projectId="@Model.Project.ProjectID" asp-route-selectedSceneId="@warning.PreviousSceneId">@warning.PreviousContextSceneDisplayName</a>
|
||||
</small>
|
||||
}
|
||||
@if (warning.CurrentSceneId.HasValue)
|
||||
{
|
||||
<small class="text-muted d-block">
|
||||
Current:
|
||||
<a asp-controller="Timeline" asp-action="Index" asp-route-projectId="@Model.Project.ProjectID" asp-route-selectedSceneId="@warning.CurrentSceneId">@warning.CurrentSceneDisplayName</a>
|
||||
<a asp-controller="Timeline" asp-action="Index" asp-route-projectId="@Model.Project.ProjectID" asp-route-selectedSceneId="@warning.CurrentSceneId">@warning.CurrentContextSceneDisplayName</a>
|
||||
</small>
|
||||
}
|
||||
@if (warning.EstablishedSceneId.HasValue)
|
||||
{
|
||||
<small class="text-muted d-block">
|
||||
Established:
|
||||
<a asp-controller="Timeline" asp-action="Index" asp-route-projectId="@Model.Project.ProjectID" asp-route-selectedSceneId="@warning.EstablishedSceneId">@warning.EstablishedSceneDisplayName</a>
|
||||
<a asp-controller="Timeline" asp-action="Index" asp-route-projectId="@Model.Project.ProjectID" asp-route-selectedSceneId="@warning.EstablishedSceneId">@(string.IsNullOrWhiteSpace(warning.EstablishedContextSceneDisplayName) ? warning.EstablishedSceneDisplayName : warning.EstablishedContextSceneDisplayName)</a>
|
||||
</small>
|
||||
}
|
||||
@if (warning.ReferencedSceneId.HasValue)
|
||||
{
|
||||
<small class="text-muted d-block">
|
||||
Earlier reference:
|
||||
<a asp-controller="Timeline" asp-action="Index" asp-route-projectId="@Model.Project.ProjectID" asp-route-selectedSceneId="@warning.ReferencedSceneId">@warning.ReferencedSceneDisplayName</a>
|
||||
<a asp-controller="Timeline" asp-action="Index" asp-route-projectId="@Model.Project.ProjectID" asp-route-selectedSceneId="@warning.ReferencedSceneId">@(string.IsNullOrWhiteSpace(warning.ReferencedContextSceneDisplayName) ? warning.ReferencedSceneDisplayName : warning.ReferencedContextSceneDisplayName)</a>
|
||||
</small>
|
||||
}
|
||||
@if (warning.IsAcknowledged && !string.IsNullOrWhiteSpace(warning.AcknowledgementNotes))
|
||||
@ -217,7 +217,7 @@
|
||||
<td>
|
||||
@if (warning.SceneID.HasValue)
|
||||
{
|
||||
<a asp-controller="Timeline" asp-action="Index" asp-route-projectId="@Model.Project.ProjectID" asp-route-selectedSceneId="@warning.SceneID">@warning.SceneDisplayName</a>
|
||||
<a asp-controller="Timeline" asp-action="Index" asp-route-projectId="@Model.Project.ProjectID" asp-route-selectedSceneId="@warning.SceneID">@warning.ContextSceneDisplayName</a>
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -239,6 +239,17 @@
|
||||
}
|
||||
</td>
|
||||
<td>
|
||||
@if (warning.CanInvestigate)
|
||||
{
|
||||
<a class="btn btn-outline-primary btn-sm"
|
||||
asp-controller="ContinuityExplorer"
|
||||
asp-action="Index"
|
||||
asp-route-projectId="@Model.Project.ProjectID"
|
||||
asp-route-mode="@warning.InvestigationDisplayMode"
|
||||
asp-route-characterId="@warning.CharacterID"
|
||||
asp-route-assetId="@warning.AssetID"
|
||||
asp-route-sceneId="@warning.InvestigationSceneId">Investigate</a>
|
||||
}
|
||||
@if (warning.Source == "Persisted" && warning.ContinuityWarningID.HasValue)
|
||||
{
|
||||
@if (warning.IsDismissed || warning.IsIntentional)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user