Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/EventLogExpert.Runtime/LogTable/ColumnDefaults.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ internal sealed class ColumnDefaults : ILogTableColumnDefaultsProvider
private static readonly FrozenDictionary<ColumnName, int> s_widths = new Dictionary<ColumnName, int>
{
[ColumnName.RecordId] = 90,
[ColumnName.Level] = 100,
[ColumnName.Level] = 115,
[ColumnName.DateAndTime] = 160,
[ColumnName.ActivityId] = 270,
[ColumnName.Log] = 100,
Expand Down
19 changes: 19 additions & 0 deletions src/EventLogExpert.UI/Common/SeverityIcon.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// // Copyright (c) Microsoft Corporation.
// // Licensed under the MIT License.

using EventLogExpert.Eventing.Common.Events;

namespace EventLogExpert.UI.Common;

internal static class SeverityIcon
{
public static string CssClass(SeverityLevel? severity) => severity switch
{
SeverityLevel.Critical => "bi bi-exclamation-octagon-fill critical",
SeverityLevel.Error => "bi bi-exclamation-circle error",
SeverityLevel.Warning => "bi bi-exclamation-triangle warning",
SeverityLevel.Information => "bi bi-info-circle",
SeverityLevel.Verbose => "bi bi-circle verbose",
_ => string.Empty
};
}
79 changes: 45 additions & 34 deletions src/EventLogExpert.UI/DetailsPane/DetailsPane.razor
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,8 @@
<div class="details-pane" data-toggle="@IsExpanded" hidden="@(_selectedEvent is null)">
<div class="details-resizer"></div>

<ChromelessButton aria-expanded="@IsExpanded"
aria-label="@(_isExpanded ? "Collapse details" : "Expand details")"
CssClass="flex-space-between"
id="details-header"
OnClick="ToggleMenu">
<span>Details</span>

<span class="menu-toggle" data-rotate="@IsExpanded">
<i class="bi bi-caret-up"></i>
</span>
</ChromelessButton>

<div class="details-body">
@if (_model is not null)
<div class="details-headerbar">
@if (_isExpanded && _model is not null)
{
<div aria-label="Event detail views" class="details-tabs" role="tablist">
<button aria-controls="details-tabpanel-reader"
Expand All @@ -27,7 +15,7 @@
@onclick="() => SetTab(DetailsTab.Reader)"
role="tab"
type="button">
Reader
Details
</button>
<button aria-controls="details-tabpanel-xml"
aria-selected="@(_activeTab == DetailsTab.Xml ? "true" : "false")"
Expand All @@ -39,13 +27,36 @@
type="button">
XML
</button>
</div>
}
else
{
<span class="details-headerbar-label">Details</span>
}

<div class="details-headerbar-actions">
@if (_isExpanded && _model is not null)
{
<button aria-label="Copy event to clipboard" class="details-copy-event" @onclick="CopyEventAsync" type="button">
<i class="bi bi-clipboard"></i>
<span class="details-copy-event-label">Copy event</span>
</button>
</div>
}
<Button CssClass="menu-toggle"
IconClass="bi bi-caret-up"
IconOnly
OnClick="ToggleMenu"
aria-controls="details-body"
aria-expanded="@IsExpanded"
aria-label="@(_isExpanded ? "Collapse details" : "Expand details")"
data-rotate="@IsExpanded"
id="details-header" />
</div>
</div>

<div class="details-body" id="details-body">
@if (_model is not null)
{
<div aria-labelledby="details-tab-reader" class="details-reader" hidden="@(_activeTab != DetailsTab.Reader)" id="details-tabpanel-reader" role="tabpanel">
@if (_activeTab == DetailsTab.Reader)
{
Expand All @@ -56,9 +67,9 @@
@if (!string.IsNullOrEmpty(_model.Level))
{
<span class="details-summary-level">
@if (SeverityDot(_model.Severity) is { } severity)
@if (SeverityIcon.CssClass(_model.Severity) is { Length: > 0 } levelIcon)
{
<span aria-hidden="true" class="details-severity-dot" data-severity="@severity" title="@($"Severity: {_model.Level}")"></span>
<span aria-hidden="true" class="level-icon @levelIcon" title="@($"Severity: {_model.Level}")"></span>
}
@_model.Level
</span>
Expand Down Expand Up @@ -211,25 +222,25 @@
</div>
</div>
}
</div>
</div>

<p aria-labelledby="details-tab-xml" class="details-xml" hidden="@(_activeTab != DetailsTab.Xml)" id="details-tabpanel-xml" role="tabpanel">
@if (_activeTab == DetailsTab.Xml)
<p aria-labelledby="details-tab-xml" class="details-xml" hidden="@(_activeTab != DetailsTab.Xml)" id="details-tabpanel-xml" role="tabpanel">
@if (_activeTab == DetailsTab.Xml)
{
@if (_resolvedXml is null)
{
<text>Resolving XML...</text>
}
else if (_resolvedXml.Length > 0)
{
@GetXmlForDisplay()
}
else
{
@if (_resolvedXml is null)
{
<text>Resolving XML...</text>
}
else if (_resolvedXml.Length > 0)
{
@GetXmlForDisplay()
}
else
{
<text>No XML available for this event.</text>
}
<text>No XML available for this event.</text>
}
</p>
}
</p>
}
</div>
</div>
9 changes: 0 additions & 9 deletions src/EventLogExpert.UI/DetailsPane/DetailsPane.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,15 +143,6 @@ protected override void OnInitialized()
base.OnInitialized();
}

// Only Error/Warning get a coloured severity dot, mirroring the log table's level colouring exactly (LevelSeverity +
// GetLevelClass); Critical/Information/Verbose/unknown show no dot, matching the table's neutral treatment there.
private static string? SeverityDot(SeverityLevel? severity) => severity switch
{
SeverityLevel.Error => "error",
SeverityLevel.Warning => "warning",
_ => null
};

private async Task CopyEventAsync()
{
if (_model is { } model)
Expand Down
59 changes: 33 additions & 26 deletions src/EventLogExpert.UI/DetailsPane/DetailsPane.razor.css
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
}
}

.details-pane[data-toggle="false"] ::deep > :not(#details-header) { display: none; }
.details-pane[data-toggle="false"] ::deep .details-body,
.details-pane[data-toggle="false"] ::deep .details-resizer { display: none; }

.details-resizer {
position: absolute;
Expand All @@ -30,22 +31,41 @@
cursor: n-resize;
}

.details-pane ::deep #details-header {
appearance: none;
padding: 0;
border: 0;
font: inherit;
text-align: left;
color: inherit;
background: none;
user-select: none;
cursor: pointer;
.details-headerbar {
container: details-headerbar / inline-size;
display: flex;
flex: 0 0 auto;
flex-wrap: wrap;
align-items: center;
gap: 0.75rem;
padding: 0 0.5rem;
border-bottom: 1px solid var(--border-divider);
}

/* Narrow pane: drop the "Copy event" text (its aria-label stays) so the toggle + tabs + copy icon keep to one
row instead of clipping under the pane's overflow:hidden; flex-wrap above is the last-resort safety. */
@container details-headerbar (max-width: 22rem) {
.details-copy-event-label { display: none; }
}

.details-headerbar-actions {
display: flex;
align-items: center;
gap: 0.5rem;
margin-left: auto;
}

.details-headerbar-label {
padding: 5px 0;
color: var(--text-primary);
font-weight: 600;
}

.details-body {
display: flex;
flex-direction: column;
height: 100%;
flex: 1 1 auto;
min-height: 0;
overflow: hidden;
}

Expand All @@ -54,8 +74,6 @@
flex: 0 0 auto;
align-items: center;
gap: 2px;
padding: 0 0.5rem;
border-bottom: 1px solid var(--border-divider);
}

.details-tab {
Expand Down Expand Up @@ -142,17 +160,7 @@
font-size: 13px;
}

.details-severity-dot {
width: 8px;
height: 8px;
flex: 0 0 auto;
border-radius: 50%;
background: var(--text-secondary);
}

.details-severity-dot[data-severity="error"] { background: var(--clr-red); }

.details-severity-dot[data-severity="warning"] { background: var(--clr-yellow); }
.details-summary-level .level-icon { margin-inline-end: 0; }

.details-grid {
display: grid;
Expand Down Expand Up @@ -281,7 +289,6 @@
align-items: center;
gap: 0.35rem;
height: 24px;
margin-left: auto;
padding: 0 0.55rem;
border: 0;
border-radius: 4px;
Expand Down
4 changes: 2 additions & 2 deletions src/EventLogExpert.UI/LogTable/LogTablePane.razor
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@
@oncontextmenu:stopPropagation="true"
role="gridcell">

@if (capturedColumn == ColumnName.Level)
@if (capturedColumn == ColumnName.Level && GetLevelClass(row.Lean.Level) is { Length: > 0 } levelIcon)
{
<span aria-hidden="true" class="@GetLevelClass(row.Lean.Level)"></span>
<span aria-hidden="true" class="level-icon @levelIcon"></span>
}

@FindableCell((EventTableColumnFormatter.GetCellText(row.Lean, capturedColumn, _timeZoneSettings), isCurrentFindMatch))
Expand Down
10 changes: 2 additions & 8 deletions src/EventLogExpert.UI/LogTable/LogTablePane.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
using EventLogExpert.Runtime.LogTable;
using EventLogExpert.Runtime.Menu;
using EventLogExpert.Runtime.Settings;
using EventLogExpert.UI.Common;
using EventLogExpert.UI.Common.Interop;
using EventLogExpert.UI.LogTable.Grouping;
using Fluxor;
Expand Down Expand Up @@ -143,14 +144,7 @@ internal static ItemsProviderResult<DisplayRow> ComputeEventViewport(
return new ItemsProviderResult<DisplayRow>(window, totalCount);
}

internal static string GetLevelClass(string level) =>
LevelSeverity.FromLevelName(level) switch
{
SeverityLevel.Error => "bi bi-exclamation-circle error",
SeverityLevel.Warning => "bi bi-exclamation-triangle warning",
SeverityLevel.Information => "bi bi-info-circle",
_ => string.Empty,
};
internal static string GetLevelClass(string level) => SeverityIcon.CssClass(LevelSeverity.FromLevelName(level));

protected override async ValueTask DisposeAsyncCore(bool disposing)
{
Expand Down
16 changes: 3 additions & 13 deletions src/EventLogExpert.UI/LogTable/LogTablePane.razor.css
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,6 @@ tr {
user-select: none;
}

.error { color: var(--clr-red); }

.warning { color: var(--clr-yellow); }

.table-row { cursor: pointer; }

.table-row.selected {
Expand All @@ -58,9 +54,7 @@ tr {
mode) can still tell which row is selected. */
box-shadow: inset 3px 0 0 var(--clr-statusbar);

& span.error { color: var(--accent-on-fill); }

& span.warning { color: var(--accent-on-fill); }
& .level-icon { color: var(--accent-on-fill); }
}

/* Single rule applies any highlight color via the [data-highlight] palette
Expand All @@ -74,9 +68,7 @@ tr {
color: var(--hl-fg);
box-shadow: inset 3px 0 0 var(--hl-fg);

& span.error { color: var(--hl-fg); }

& span.warning { color: var(--hl-fg); }
& .level-icon { color: var(--hl-fg); }
}

/* Selected + highlighted rows: stack both cues so neither state is lost.
Expand Down Expand Up @@ -104,9 +96,7 @@ tr {
box-shadow: inset 3px 0 0 MarkText;
forced-color-adjust: none;

& span.error { color: MarkText; }

& span.warning { color: MarkText; }
& .level-icon { color: MarkText; }
}

.table-row.selected[data-highlight] {
Expand Down
15 changes: 15 additions & 0 deletions src/EventLogExpert.UI/wwwroot/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,21 @@ a { color: var(--clr-lightblue); }

.validation-message { color: var(--clr-red); }

.level-icon {
display: inline-block;
width: 1em;
margin-inline-end: .4rem;
text-align: center;
}

.level-icon.critical { color: var(--clr-red); }

.level-icon.error { color: var(--clr-red); }

.level-icon.warning { color: var(--clr-yellow); }

.level-icon.verbose { color: var(--text-secondary); }

.blazor-error-boundary {
background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
padding: 1rem 1rem 1rem 3.7rem;
Expand Down
Loading
Loading