Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
44cd028
Extract Modal/Alert broker, move System/File/Clipboard to Common
jschick04 May 10, 2026
a2a7c61
Move Clipboard port to Common, rename CopyType to EventCopyFormat
jschick04 May 10, 2026
09f9bb6
Move IPreferencesProvider port to Common/Preferences/
jschick04 May 10, 2026
79bad80
Move Versioning ports to Common/Versioning/
jschick04 May 10, 2026
255293a
Move AppTitle ports to Common/AppTitle/
jschick04 May 10, 2026
c2afc03
Move IMainThreadService to Common/Threading/
jschick04 May 10, 2026
235f048
Move IWindowsIdentityProvider to Common/Identity/
jschick04 May 11, 2026
2fdf113
Move LoggingMiddleware to Common/Logging/
jschick04 May 11, 2026
e827258
Move DisplayExtensions to Common/Display/
jschick04 May 11, 2026
9abb2b4
Promote StatusBar slice
jschick04 May 11, 2026
8c2e323
Promote DebugLog slice
jschick04 May 11, 2026
59371d0
Promote Banner slice
jschick04 May 11, 2026
c94e60f
Promote Modal slice
jschick04 May 11, 2026
4b25357
Promote Alerts slice and rename ModalAlertDialogService to AlertDialo…
jschick04 May 11, 2026
31d73a0
Promote Settings slice
jschick04 May 11, 2026
db1edf2
Promote Menu slice
jschick04 May 11, 2026
b7f93c5
Promote Database slice
jschick04 May 11, 2026
4af675d
Promote Update slice and move ApplicationRestart port to Common/
jschick04 May 11, 2026
f928100
Promote Deployment subfolder under Update/
jschick04 May 11, 2026
05168bc
Promote ReleaseNotes subfolder; relocate Markdown helpers to Common/
jschick04 May 11, 2026
183901d
Promote LogTable slice (was EventTable) with LogView record and LogTa…
jschick04 May 11, 2026
1c8c134
Promote EventLog slice with EventLogData and EventLogId types
jschick04 May 11, 2026
fcd3618
Promote Filter slice with SavedFilter/SavedFilterGroup/FilterDraft/Da…
jschick04 May 11, 2026
045f57a
Promote FilterCache slice with CacheType
jschick04 May 11, 2026
811fdd3
Promote FilterGroup slice
jschick04 May 11, 2026
85e6f64
Promote FilterPane slice
jschick04 May 11, 2026
01a7e83
Cleanup legacy folders and relocate orphan files
jschick04 May 11, 2026
3d2522e
Rename FilterDraft.FromFilterModel and internalize SavedFilterJsonCon…
jschick04 May 11, 2026
4b6160a
Rename GitReleaseModel to GitHubRelease (drop *Model suffix)
jschick04 May 11, 2026
6742598
Add BannerId record and replace raw Guid in Banner surface
jschick04 May 11, 2026
1633161
Add UpgradeBatchId record and replace raw Guid in Database.Upgrade su…
jschick04 May 11, 2026
cb53e33
Add StatusActivityId record and replace raw Guid in StatusBar surface
jschick04 May 11, 2026
f7c9945
Move internal GitHubReleaseNormalizer next to UpdateService consumer
jschick04 May 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
16 changes: 9 additions & 7 deletions src/EventLogExpert.Components/BannerHost.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
// // Licensed under the MIT License.

using EventLogExpert.Eventing.Logging;
using EventLogExpert.UI.Interfaces;
using EventLogExpert.UI.Models;
using EventLogExpert.UI.Services;
using EventLogExpert.UI.Banner;
using EventLogExpert.UI.Common.Clipboard;
using EventLogExpert.UI.Common.Restart;
using EventLogExpert.UI.Database;
using EventLogExpert.UI.Menu;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;

Expand Down Expand Up @@ -140,9 +142,9 @@ private void OnCyclePrev()

private void OnDismissAttention() => BannerService.DismissAttention();

private void OnDismissError(Guid id) => BannerService.DismissError(id);
private void OnDismissError(BannerId id) => BannerService.DismissError(id);

private void OnDismissInfo(Guid id) => BannerService.DismissInfoBanner(id);
private void OnDismissInfo(BannerId id) => BannerService.DismissInfoBanner(id);

private async Task OnErrorActionClickedAsync(Func<Task> action)
{
Expand Down Expand Up @@ -178,7 +180,7 @@ private async Task OnOpenSettingsClickedAsync()
{
TraceLogger.Error($"{nameof(BannerHost)}.{nameof(OnOpenSettingsClickedAsync)}: open settings threw: {ex}");

Guid errorId = BannerService.ReportError("Settings", $"Failed to open settings: {ex.Message}");
BannerId errorId = BannerService.ReportError("Settings", $"Failed to open settings: {ex.Message}");
_selectedItem = new BannerCycleItem(BannerView.Error, 0, errorId);

return;
Expand All @@ -188,7 +190,7 @@ private async Task OnOpenSettingsClickedAsync()
{
TraceLogger.Error($"{nameof(BannerHost)}.{nameof(OnOpenSettingsClickedAsync)}: open settings returned false");

Guid errorId = BannerService.ReportError("Settings", "Failed to open settings; try again from the menu.");
BannerId errorId = BannerService.ReportError("Settings", "Failed to open settings; try again from the menu.");
_selectedItem = new BannerCycleItem(BannerView.Error, 0, errorId);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/EventLogExpert.Components/Base/InputComponent.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// // Copyright (c) Microsoft Corporation.
// // Licensed under the MIT License.

using EventLogExpert.UI.Models;
using EventLogExpert.UI.Common.Display;
using Microsoft.AspNetCore.Components;

namespace EventLogExpert.Components.Base;
Expand Down
32 changes: 18 additions & 14 deletions src/EventLogExpert.Components/Base/ModalBase.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
// // Copyright (c) Microsoft Corporation.
// // Licensed under the MIT License.

using EventLogExpert.UI.Interfaces;
using EventLogExpert.UI.Alerts;
using EventLogExpert.UI.Modal;
using Fluxor.Blazor.Web.Components;
using Microsoft.AspNetCore.Components;

Expand All @@ -18,6 +19,8 @@ public abstract class ModalBase<TResult> : FluxorComponent, IInlineAlertHost
private InlineAlertEntry? _activeInlineAlert;
private long _modalId;

[Inject] internal IInlineAlertHostBroker InlineAlertHostBroker { get; init; } = null!;

[Inject] internal IModalService ModalService { get; init; } = null!;

/// <summary>Bound by concrete modals via <c>@ref</c> on their <see cref="ModalChrome" />.</summary>
Expand Down Expand Up @@ -66,17 +69,6 @@ public Task<InlineAlertResult> ShowInlineAlertAsync(InlineAlertRequest request,
return tcs.Task;
}

// Route Esc/native-close through OnCancelAsync so all close paths share the same pipeline.
// Protected so derived modals' .razor markup can wire OnDialogClosedByUser="HandleDialogClosedByUserAsync"
// even when the derived class lives in a different assembly than ModalBase.
protected Task HandleDialogClosedByUserAsync() => OnCancelAsync();

protected Task HandleInlineAlertResolvedAsync(InlineAlertResult result)
{
TryClearInlineAlert(null, result, false);
return Task.CompletedTask;
}

protected async Task CompleteAsync(TResult? result)
{
await OnClosingAsync();
Expand Down Expand Up @@ -105,7 +97,7 @@ protected override async ValueTask DisposeAsyncCore(bool disposing)
pending?.CancellationRegistration.Dispose();
pending?.Tcs.TrySetCanceled();

ModalService.UnregisterActiveAlertHost(_modalId);
InlineAlertHostBroker.Unregister(_modalId);

// Defensive: complete the task if we were torn down without an explicit close path.
// Stale ids are ignored, so this is a no-op when Complete already ran.
Expand All @@ -115,6 +107,18 @@ protected override async ValueTask DisposeAsyncCore(bool disposing)
await base.DisposeAsyncCore(disposing);
}

// Route Esc/native-close through OnCancelAsync so all close paths share the same pipeline.
// Protected so derived modals' .razor markup can wire OnDialogClosedByUser="HandleDialogClosedByUserAsync"
// even when the derived class lives in a different assembly than ModalBase.
protected Task HandleDialogClosedByUserAsync() => OnCancelAsync();

protected Task HandleInlineAlertResolvedAsync(InlineAlertResult result)
{
TryClearInlineAlert(null, result, false);

return Task.CompletedTask;
}

protected virtual Task OnAcceptAsync() => CompleteAsync(default);

protected virtual Task OnCancelAsync() => CompleteAsync(default);
Expand All @@ -130,7 +134,7 @@ protected override void OnInitialized()
{
// Capture the active id so a stale modal can never complete a successor's task.
_modalId = ModalService.ActiveModalId;
ModalService.RegisterActiveAlertHost(_modalId, this);
InlineAlertHostBroker.Register(_modalId, this);
base.OnInitialized();
}

Expand Down
24 changes: 12 additions & 12 deletions src/EventLogExpert.Components/Base/ModalChrome.razor.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// // Copyright (c) Microsoft Corporation.
// // Licensed under the MIT License.

using EventLogExpert.UI.Interfaces;
using EventLogExpert.UI.Alerts;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;

Expand Down Expand Up @@ -174,17 +174,6 @@ private async Task FocusInlineAlertElementAsync()
}
}

private void ResetInlineAlertPromptValueIfChanged()
{
if (ReferenceEquals(_inlineAlertInitializedFor, InlineAlert)) { return; }

_inlineAlertInitializedFor = InlineAlert;

_inlineAlertPromptValue = InlineAlert is { IsPrompt: true }
? InlineAlert.PromptInitialValue ?? string.Empty
: string.Empty;
}

private Task HandleAcceptAsync() => OnAccept.InvokeAsync();

private Task HandleCancelButtonAsync() => OnCancel.InvokeAsync();
Expand Down Expand Up @@ -243,4 +232,15 @@ private Task HandleInlineAlertCancelAsync() =>
OnInlineAlertResolved.InvokeAsync(new InlineAlertResult(false, null));

private Task HandleSaveAsync() => OnSave.InvokeAsync();

private void ResetInlineAlertPromptValueIfChanged()
{
if (ReferenceEquals(_inlineAlertInitializedFor, InlineAlert)) { return; }

_inlineAlertInitializedFor = InlineAlert;

_inlineAlertPromptValue = InlineAlert is { IsPrompt: true }
? InlineAlert.PromptInitialValue ?? string.Empty
: string.Empty;
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
// // Copyright (c) Microsoft Corporation.
// // Licensed under the MIT License.

using EventLogExpert.UI;
using EventLogExpert.UI.Models;
using EventLogExpert.UI.Database;
using Microsoft.AspNetCore.Components;

namespace EventLogExpert.Components.Database;

public sealed partial class DatabaseEntryRow : ComponentBase
{
/// <summary>
/// Click-driven reveal flag for the trash strip on the left of the row. Set true when the
/// name button is clicked, cleared when the cursor leaves the row -- so re-entering the row
/// without re-clicking does not re-open the slide, even though the name button may still
/// hold DOM focus. Keyboard navigation drives the reveal via :focus-visible in CSS instead.
/// Click-driven reveal flag for the trash strip on the left of the row. Set true when the name button is clicked,
/// cleared when the cursor leaves the row -- so re-entering the row without re-clicking does not re-open the slide,
/// even though the name button may still hold DOM focus. Keyboard navigation drives the reveal via :focus-visible in
/// CSS instead.
/// </summary>
private bool _isMouseRevealed;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
@using EventLogExpert.Components.Base
@if (!_isDismissed && _entries.Count > 0)
{
<ModalChrome AcceptLabel="Apply"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

using EventLogExpert.Components.Base;
using EventLogExpert.Eventing.Logging;
using EventLogExpert.UI.Interfaces;
using EventLogExpert.UI.Models;
using EventLogExpert.UI.Banner;
using EventLogExpert.UI.Database;
using Microsoft.AspNetCore.Components;

namespace EventLogExpert.Components.Database;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
// // Licensed under the MIT License.

using EventLogExpert.Eventing.Logging;
using EventLogExpert.UI.Interfaces;
using EventLogExpert.UI.Models;
using EventLogExpert.UI.Banner;
using EventLogExpert.UI.Database;
using Microsoft.AspNetCore.Components;

namespace EventLogExpert.Components.Database;
Expand All @@ -13,7 +13,7 @@ public sealed partial class DatabaseRecoveryHost : ComponentBase, IDisposable
private bool _dialogOpen;
private bool _disposed;
private HashSet<string> _promptedFor = new(StringComparer.OrdinalIgnoreCase);
private Guid? _recoveryBannerId;
private BannerId? _recoveryBannerId;

[Inject] private IBannerService BannerService { get; init; } = null!;

Expand Down Expand Up @@ -43,6 +43,14 @@ protected override void OnInitialized()
EvaluateState();
}

private void DismissCurrentBannerIfAny()
{
if (_recoveryBannerId is not { } activeId) { return; }

BannerService.DismissError(activeId);
_recoveryBannerId = null;
}

private void EvaluateState()
{
if (_disposed) { return; }
Expand All @@ -68,14 +76,6 @@ private void EvaluateState()
_promptedFor = currentBackupSet;
}

private void DismissCurrentBannerIfAny()
{
if (_recoveryBannerId is not { } activeId) { return; }

BannerService.DismissError(activeId);
_recoveryBannerId = null;
}

private void HandleBannerStateChanged()
{
if (_disposed) { return; }
Expand Down Expand Up @@ -112,7 +112,7 @@ private Task OpenRecoveryDialogAsync()
});
}

private Guid ReportRecoveryBanner(int count)
private BannerId ReportRecoveryBanner(int count)
{
string message = count == 1
? "1 database needs recovery from interrupted upgrade."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
// // Licensed under the MIT License.

using EventLogExpert.Eventing.Logging;
using EventLogExpert.UI.Interfaces;
using EventLogExpert.UI.Models;
using EventLogExpert.UI.Banner;
using Microsoft.AspNetCore.Components;

namespace EventLogExpert.Components.Database;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
// // Licensed under the MIT License.

using EventLogExpert.Components.Filters.Base;
using EventLogExpert.UI.Models;
using EventLogExpert.UI.Store.FilterPane;
using EventLogExpert.UI.Filter;
using EventLogExpert.UI.FilterPane;

namespace EventLogExpert.Components.Filters;

Expand All @@ -13,15 +13,15 @@ protected override void DispatchRemoveFilter()
{
if (Value is not { } savedFilter) { return; }

Dispatcher.Dispatch(new FilterPaneAction.RemoveFilter(savedFilter.Id));
Dispatcher.Dispatch(new RemoveFilterAction(savedFilter.Id));
}

protected override void DispatchSetFilter(FilterModel filter) =>
Dispatcher.Dispatch(new FilterPaneAction.SetFilter(filter));
protected override void DispatchSetFilter(SavedFilter filter) =>
Dispatcher.Dispatch(new SetFilterAction(filter));

protected override void DispatchToggleEnabled(FilterId id) =>
Dispatcher.Dispatch(new FilterPaneAction.ToggleFilterEnabled(id));
Dispatcher.Dispatch(new ToggleFilterEnabledAction(id));

protected override void DispatchToggleExclusion(FilterId id) =>
Dispatcher.Dispatch(new FilterPaneAction.ToggleFilterExcluded(id));
Dispatcher.Dispatch(new ToggleFilterExcludedAction(id));
}
Loading
Loading