308 lines
18 KiB
Plaintext
308 lines
18 KiB
Plaintext
@model WarningDashboardViewModel
|
|
@{
|
|
ViewData["Title"] = "Continuity Warnings";
|
|
ViewData["ProjectSection"] = "Warnings";
|
|
}
|
|
|
|
@functions {
|
|
private static string SeverityBadgeClass(string severity) => severity switch
|
|
{
|
|
"Critical" => "bg-danger",
|
|
"Warning" => "bg-warning text-dark",
|
|
_ => "bg-info text-dark"
|
|
};
|
|
}
|
|
|
|
<nav class="breadcrumb-trail" aria-label="Breadcrumb">
|
|
<a asp-controller="Projects" asp-action="Index">Projects</a>
|
|
<a asp-controller="Projects" asp-action="Details" asp-route-id="@Model.Project.ProjectID">@Model.Project.ProjectName</a>
|
|
<span>Warnings</span>
|
|
</nav>
|
|
|
|
<partial name="_ProjectSectionNav" model="Model.Project" />
|
|
|
|
<div class="page-heading compact">
|
|
<div>
|
|
<p class="eyebrow">Continuity</p>
|
|
<h1>@Model.Project.ProjectName <help-icon key="warnings.overview" /></h1>
|
|
</div>
|
|
<div class="button-row">
|
|
<form asp-action="ValidateProject" method="post">
|
|
<input type="hidden" name="projectId" value="@Model.Project.ProjectID" />
|
|
<input type="hidden" name="bookId" value="@Model.BookID" />
|
|
<button class="btn btn-primary" type="submit">Validate project</button>
|
|
</form>
|
|
@if (Model.BookID.HasValue)
|
|
{
|
|
<form asp-action="ValidateBook" method="post">
|
|
<input type="hidden" name="projectId" value="@Model.Project.ProjectID" />
|
|
<input type="hidden" name="bookId" value="@Model.BookID" />
|
|
<button class="btn btn-outline-primary" type="submit">Validate book</button>
|
|
</form>
|
|
}
|
|
</div>
|
|
</div>
|
|
|
|
@if (Model.LastValidationSummary is not null)
|
|
{
|
|
<section class="validation-summary">
|
|
<strong>Validation complete.</strong>
|
|
<span>@Model.LastValidationSummary.ErrorCount errors</span>
|
|
<span>@Model.LastValidationSummary.WarningCount warnings</span>
|
|
<span>@Model.LastValidationSummary.InfoCount info</span>
|
|
</section>
|
|
}
|
|
|
|
<section class="warning-filter-panel">
|
|
<form method="get" class="row g-2 align-items-end">
|
|
<input type="hidden" name="projectId" value="@Model.Project.ProjectID" />
|
|
<div class="col-md-3">
|
|
<label class="form-label">Book</label>
|
|
<select name="bookId" asp-items="Model.BookOptions" class="form-select form-select-sm">
|
|
<option value="">All books</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<label class="form-label">Chapter</label>
|
|
<select name="chapterId" asp-items="Model.ChapterOptions" class="form-select form-select-sm">
|
|
<option value="">All chapters</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<label class="form-label">Category</label>
|
|
<select name="category" asp-items="Model.CategoryOptions" class="form-select form-select-sm">
|
|
<option value="">All categories</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<label class="form-label">Type</label>
|
|
<select name="warningTypeId" asp-items="Model.WarningTypeOptions" class="form-select form-select-sm">
|
|
<option value="">All types</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<label class="form-label">Severity</label>
|
|
<select name="warningSeverityId" asp-items="Model.SeverityOptions" class="form-select form-select-sm">
|
|
<option value="">All severities</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<label class="form-label">Entity</label>
|
|
<select name="entityType" asp-items="Model.EntityTypeOptions" class="form-select form-select-sm">
|
|
<option value="">All entities</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<label class="form-check">
|
|
<input class="form-check-input" name="includeDismissed" type="checkbox" value="true" checked="@Model.IncludeDismissed" />
|
|
<span class="form-check-label">Dismissed</span>
|
|
</label>
|
|
<label class="form-check">
|
|
<input class="form-check-input" name="includeIntentional" type="checkbox" value="true" checked="@Model.IncludeIntentional" />
|
|
<span class="form-check-label">Intentional</span>
|
|
</label>
|
|
<label class="form-check">
|
|
<input class="form-check-input" name="showAcknowledgedWarnings" type="checkbox" value="true" checked="@Model.ShowAcknowledgedWarnings" />
|
|
<span class="form-check-label">Acknowledged</span>
|
|
</label>
|
|
</div>
|
|
<div class="col-12">
|
|
<button class="btn btn-outline-primary btn-sm" type="submit">Filter warnings</button>
|
|
</div>
|
|
</form>
|
|
</section>
|
|
|
|
<section class="warning-dashboard-grid">
|
|
<article class="plain-card">
|
|
<h2>By severity <help-icon key="warnings.severitySummary" /></h2>
|
|
@foreach (var count in Model.CountsBySeverity)
|
|
{
|
|
<div class="warning-count-row">
|
|
<span class="severity-pill @count.Key.ToLowerInvariant()">@count.Key</span>
|
|
<strong>@count.Value</strong>
|
|
</div>
|
|
}
|
|
</article>
|
|
<article class="plain-card">
|
|
<h2>By type <help-icon key="warnings.typeSummary" /></h2>
|
|
@foreach (var count in Model.CountsByType.Take(8))
|
|
{
|
|
<div class="warning-count-row">
|
|
<span>@count.Key</span>
|
|
<strong>@count.Value</strong>
|
|
</div>
|
|
}
|
|
</article>
|
|
</section>
|
|
|
|
<section class="list-section">
|
|
<h2>Warnings <help-icon key="warnings.list" /></h2>
|
|
@if (!Model.ProjectWarnings.Any())
|
|
{
|
|
<p class="muted">@(Model.HasAnyWarnings ? "No warnings match the current filters." : "No project warnings detected.")</p>
|
|
}
|
|
else
|
|
{
|
|
<div class="table-responsive">
|
|
<table class="table table-sm align-middle">
|
|
<thead>
|
|
<tr>
|
|
<th>Severity</th>
|
|
<th>Category</th>
|
|
<th>Warning Type</th>
|
|
<th>Message</th>
|
|
<th>Book</th>
|
|
<th>Chapter</th>
|
|
<th>Scene</th>
|
|
<th>Status</th>
|
|
<th>Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@foreach (var warning in Model.ProjectWarnings)
|
|
{
|
|
<tr>
|
|
<td><span class="badge @SeverityBadgeClass(warning.Severity)">@warning.Severity</span></td>
|
|
<td>@warning.Category</td>
|
|
<td>@warning.WarningTypeDisplayName</td>
|
|
<td>
|
|
<div>@warning.Message</div>
|
|
@if (!string.IsNullOrWhiteSpace(warning.Details))
|
|
{
|
|
<small class="text-muted d-block">@warning.Details</small>
|
|
}
|
|
@if (!string.IsNullOrWhiteSpace(warning.KnowledgeTitle))
|
|
{
|
|
<small class="text-muted d-block">Knowledge: @warning.KnowledgeTitle</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>
|
|
</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>
|
|
</small>
|
|
}
|
|
@if (warning.IsAcknowledged && !string.IsNullOrWhiteSpace(warning.AcknowledgementNotes))
|
|
{
|
|
<small class="text-muted d-block">Note: @warning.AcknowledgementNotes</small>
|
|
}
|
|
</td>
|
|
<td>@(string.IsNullOrWhiteSpace(warning.BookDisplayName) ? "Project" : warning.BookDisplayName)</td>
|
|
<td>@(string.IsNullOrWhiteSpace(warning.ChapterDisplayName) ? "-" : warning.ChapterDisplayName)</td>
|
|
<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>
|
|
}
|
|
else
|
|
{
|
|
<span class="muted">Project-wide</span>
|
|
}
|
|
</td>
|
|
<td>
|
|
@if (warning.IsDismissed)
|
|
{
|
|
<span class="badge bg-secondary">Dismissed</span>
|
|
}
|
|
else if (warning.IsIntentional || warning.IsAcknowledged)
|
|
{
|
|
<span class="badge bg-secondary">Acknowledged</span>
|
|
}
|
|
else
|
|
{
|
|
<span class="badge bg-warning text-dark">Active</span>
|
|
}
|
|
</td>
|
|
<td>
|
|
@if (warning.Source == "Persisted" && warning.ContinuityWarningID.HasValue)
|
|
{
|
|
@if (warning.IsDismissed || warning.IsIntentional)
|
|
{
|
|
<form asp-action="Restore" method="post" class="d-inline">
|
|
<input type="hidden" name="id" value="@warning.ContinuityWarningID" />
|
|
<input type="hidden" name="projectId" value="@Model.Project.ProjectID" />
|
|
<input type="hidden" name="bookId" value="@Model.BookID" />
|
|
<input type="hidden" name="sceneId" value="@Model.SceneID" />
|
|
<button class="btn btn-outline-secondary btn-sm" type="submit">Restore</button>
|
|
</form>
|
|
}
|
|
else
|
|
{
|
|
<form asp-action="Dismiss" method="post" class="d-inline">
|
|
<input type="hidden" name="id" value="@warning.ContinuityWarningID" />
|
|
<input type="hidden" name="projectId" value="@Model.Project.ProjectID" />
|
|
<input type="hidden" name="bookId" value="@Model.BookID" />
|
|
<input type="hidden" name="sceneId" value="@Model.SceneID" />
|
|
<button class="btn btn-outline-secondary btn-sm" type="submit">Dismiss</button>
|
|
</form>
|
|
<form asp-action="MarkIntentional" method="post" class="d-inline">
|
|
<input type="hidden" name="id" value="@warning.ContinuityWarningID" />
|
|
<input type="hidden" name="projectId" value="@Model.Project.ProjectID" />
|
|
<input type="hidden" name="bookId" value="@Model.BookID" />
|
|
<input type="hidden" name="sceneId" value="@Model.SceneID" />
|
|
<button class="btn btn-outline-secondary btn-sm" type="submit">Intentional</button>
|
|
</form>
|
|
}
|
|
}
|
|
else
|
|
{
|
|
@if (warning.IsAcknowledged)
|
|
{
|
|
<form asp-action="RestoreGeneratedWarning" method="post" class="d-inline">
|
|
<input type="hidden" name="WarningType" value="@warning.WarningType" />
|
|
<input type="hidden" name="SceneID" value="@warning.SceneID" />
|
|
<input type="hidden" name="CharacterID" value="@warning.CharacterID" />
|
|
<input type="hidden" name="AssetID" value="@warning.AssetID" />
|
|
<input type="hidden" name="ReturnFilter.ProjectID" value="@Model.Project.ProjectID" />
|
|
<input type="hidden" name="ReturnFilter.BookID" value="@Model.BookID" />
|
|
<input type="hidden" name="ReturnFilter.ChapterID" value="@Model.ChapterID" />
|
|
<input type="hidden" name="ReturnFilter.SceneID" value="@Model.SceneID" />
|
|
<input type="hidden" name="ReturnFilter.WarningTypeID" value="@Model.WarningTypeID" />
|
|
<input type="hidden" name="ReturnFilter.WarningSeverityID" value="@Model.WarningSeverityID" />
|
|
<input type="hidden" name="ReturnFilter.EntityType" value="@Model.EntityType" />
|
|
<input type="hidden" name="ReturnFilter.Category" value="@Model.Category" />
|
|
<input type="hidden" name="ReturnFilter.IncludeDismissed" value="@Model.IncludeDismissed" />
|
|
<input type="hidden" name="ReturnFilter.IncludeIntentional" value="@Model.IncludeIntentional" />
|
|
<input type="hidden" name="ReturnFilter.ShowAcknowledgedWarnings" value="@Model.ShowAcknowledgedWarnings" />
|
|
<button class="btn btn-outline-secondary btn-sm" type="submit">Restore</button>
|
|
</form>
|
|
}
|
|
else
|
|
{
|
|
<form asp-action="AcknowledgeGeneratedWarning" method="post" class="d-flex gap-1 align-items-center">
|
|
<input type="hidden" name="WarningType" value="@warning.WarningType" />
|
|
<input type="hidden" name="SceneID" value="@warning.SceneID" />
|
|
<input type="hidden" name="CharacterID" value="@warning.CharacterID" />
|
|
<input type="hidden" name="AssetID" value="@warning.AssetID" />
|
|
<input type="hidden" name="ReturnFilter.ProjectID" value="@Model.Project.ProjectID" />
|
|
<input type="hidden" name="ReturnFilter.BookID" value="@Model.BookID" />
|
|
<input type="hidden" name="ReturnFilter.ChapterID" value="@Model.ChapterID" />
|
|
<input type="hidden" name="ReturnFilter.SceneID" value="@Model.SceneID" />
|
|
<input type="hidden" name="ReturnFilter.WarningTypeID" value="@Model.WarningTypeID" />
|
|
<input type="hidden" name="ReturnFilter.WarningSeverityID" value="@Model.WarningSeverityID" />
|
|
<input type="hidden" name="ReturnFilter.EntityType" value="@Model.EntityType" />
|
|
<input type="hidden" name="ReturnFilter.Category" value="@Model.Category" />
|
|
<input type="hidden" name="ReturnFilter.IncludeDismissed" value="@Model.IncludeDismissed" />
|
|
<input type="hidden" name="ReturnFilter.IncludeIntentional" value="@Model.IncludeIntentional" />
|
|
<input type="hidden" name="ReturnFilter.ShowAcknowledgedWarnings" value="@Model.ShowAcknowledgedWarnings" />
|
|
<input class="form-control form-control-sm" type="text" name="Notes" maxlength="500" placeholder="Optional note" />
|
|
<button class="btn btn-outline-primary btn-sm" type="submit">Acknowledge</button>
|
|
</form>
|
|
}
|
|
}
|
|
</td>
|
|
</tr>
|
|
}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
}
|
|
</section>
|