Skip to content

Add typed launchers routing menu and FilterPane modal opens through coordinator#548

Merged
jschick04 merged 1 commit into
jschick/modal-coordinator-refactorfrom
jschick/modal-coordinator-pr4
May 26, 2026
Merged

Add typed launchers routing menu and FilterPane modal opens through coordinator#548
jschick04 merged 1 commit into
jschick/modal-coordinator-refactorfrom
jschick/modal-coordinator-pr4

Conversation

@jschick04
Copy link
Copy Markdown
Collaborator

Summary

PR 4 of the IModalCoordinator SoC refactor. Migrates 5 production modal-open call sites + 1 modal-state read from IModalService.Show<> (bypasses the close-veto pipeline) to IModalCoordinator.PushAsync<> (routes through it).

Stacks on top of #546 (PR 1+2+3 combined; PR 3 was merged in by the user).

Behavior FIX (not just refactor)

PR 3 added OnRequestCloseAsync overrides to SettingsModal (vetoes when IsCloseBlocked) and DatabaseToolsModal (confirm prompt when AnyTabIsRunning). But until PR 4, all production callers still went through IModalService.Show<> — bypassing the new veto handlers. This PR routes them through PushAsync<>, which fixes two pre-existing data-loss bugs:

  • Clicking Settings while Settings has unsaved changes (IsCloseBlocked=true) no longer silently nukes the existing modal.
  • Clicking Database Tools mid-tab-operation now triggers the existing "An operation is running. Cancel and close anyway?" confirm prompt instead of silently orphaning the operation.

Both were broken since PR 3 landed; the veto handlers existed but no caller exercised them. Testers should verify both flows.

New surface

src/EventLogExpert.UI/Modal/ModalCoordinatorLaunchers.cs — 6 extension methods on IModalCoordinator:

  • OpenSettingsAsync()
  • OpenDatabaseToolsAsync()
  • OpenDebugLogsAsync()
  • OpenReleaseNotesAsync(ReleaseNotesContent)
  • OpenFilterCacheAsync()
  • OpenFilterGroupAsync()

All return Task<ModalOpenResult<bool>>. Each null-guards the coordinator argument.

Migrated callers

Caller Change
MauiProgram.cs:120-145 AlertDialogService factory Two inline closures rewritten to call modalCoordinator.PushAsync<AlertModal/PromptModal, …> directly; IModalService dependency removed from the factory
MauiMenuActionService.cs Ctor injection swapped from IModalService to IModalCoordinator; ShowModalAsync<T> helper body changed from Show<>; return true to _ = PushAsync<>; return true (the helper covers Settings, DatabaseTools, DebugLogs); ShowReleaseNotesAsync uses the new extension method
FilterPane.razor.cs [Inject] IModalService ModalService[Inject] IModalCoordinator ModalCoordinator; OpenCachedFiltersModal/OpenFilterGroupsModal use extension methods
KeyboardShortcutService.cs Ctor injection swapped + modal-gate read changed from _modalService.ActiveModalType is not null to _modalCoordinator.ActiveSession is not null (SoC consistency — it's a state-read, not a launcher)

Veto contract (preserved)

MauiMenuActionService.ShowModalAsync<T> helper:

  • Opened normally → returns true
  • Vetoed (user kept current modal) → returns true (non-error; consistent with "user state preserved")
  • Exception → returns false (existing failure path; BannerHost shows the existing error banner)

BannerHost.razor.cs:189-195's if (!success) only fires on actual exceptions, never on user-vetoed close.

AlertDialogService standalone closures:

  • Alert: r.WasOpened && r.Result — veto-preempt collapses to false (caller interprets as "user dismissed")
  • Prompt: r.WasOpened ? r.Result ?? string.Empty : string.Empty — veto returns string.Empty (existing "empty-on-cancel" contract)

Tests

8 new tests in ModalCoordinatorLaunchersTests:

  • 6 verify each extension method delegates to PushAsync<TModal, bool> via NSubstitute Received(1)
  • 1 null-coordinator guard test
  • 1 veto-preempt regression test: OpenSettingsAsync returns WasOpened=false when the coordinator vetoes

918 Runtime + 158 UI = 1,076 tests passing; build 0/0.

Pre-implementation panel

4-slot panel (Opus xhigh + GPT-5.5 + GPT-5.4 + Opus 4.6) iterated R1→R3 to 4/4 unanimous READY. R2 surfaced a critical blind spot: Slot 3 caught that vetoes are reachable TODAY (not deferred to PR 5) because PR 3 added the OnRequestCloseAsync overrides. Three of four slots (and the agent) had missed this — tracked as a panel-miss for the post-PR-review feedback loop.

Follow-up work this PR unblocks

@jschick04 jschick04 requested a review from a team as a code owner May 26, 2026 02:20
@jschick04 jschick04 marked this pull request as draft May 26, 2026 02:21
@jschick04 jschick04 requested a review from Copilot May 26, 2026 02:21
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Routes production modal opens through IModalCoordinator.PushAsync<> (instead of IModalService.Show<>) so that modal preemption respects the close-veto pipeline introduced in earlier refactor PRs, preventing data-loss scenarios when users have unsaved/running work in an existing modal.

Changes:

  • Added typed IModalCoordinator launcher extensions (ModalCoordinatorLaunchers) for common modals (Settings/DatabaseTools/DebugLogs/ReleaseNotes/FilterCache/FilterGroup).
  • Migrated multiple production call sites (MAUI menu actions, FilterPane, alert/prompt factories) to use the coordinator-based open path.
  • Updated keyboard shortcut modal gating to read coordinator state (ActiveSession) and added unit tests validating launcher delegation + veto-preempt behavior.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/EventLogExpert.UI/Modal/ModalCoordinatorLaunchers.cs Adds typed coordinator-based modal launcher extensions that route through the veto pipeline.
src/EventLogExpert/MauiProgram.cs Updates alert/prompt modal open delegates to use IModalCoordinator.PushAsync<> instead of bypassing veto via IModalService.Show<>.
src/EventLogExpert/Adapters/Menu/MauiMenuActionService.cs Switches menu-driven modal opens (including release notes) from IModalService to IModalCoordinator.
src/EventLogExpert.UI/FilterPane/FilterPane.razor.cs Updates FilterPane modal opens (cached filters, filter groups) to use typed coordinator launchers.
src/EventLogExpert/Adapters/Input/KeyboardShortcutService.cs Gates shortcuts based on coordinator session state instead of modal service type state.
tests/Unit/EventLogExpert.UI.Tests/Modal/ModalCoordinatorLaunchersTests.cs Adds unit coverage for typed launcher extensions, including null-guard and veto-preempt regression behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/EventLogExpert/Adapters/Menu/MauiMenuActionService.cs
@jschick04 jschick04 force-pushed the jschick/modal-coordinator-pr4 branch from 169370d to 337a63b Compare May 26, 2026 03:13
@jschick04 jschick04 requested a review from Copilot May 26, 2026 03:16
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Comment thread src/EventLogExpert.UI/Modal/ModalCoordinatorLaunchers.cs
@jschick04 jschick04 force-pushed the jschick/modal-coordinator-pr4 branch from 337a63b to 3fd3a17 Compare May 26, 2026 03:34
@jschick04 jschick04 requested a review from Copilot May 26, 2026 03:36
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Comment thread src/EventLogExpert.UI/FilterPane/FilterPane.razor.cs Outdated
Comment thread src/EventLogExpert.UI/FilterPane/FilterPane.razor.cs Outdated
@jschick04 jschick04 force-pushed the jschick/modal-coordinator-pr4 branch from 3fd3a17 to f471c0b Compare May 26, 2026 03:48
@jschick04 jschick04 requested a review from Copilot May 26, 2026 03:49
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.

Comment thread src/EventLogExpert/MauiProgram.cs
Comment thread src/EventLogExpert/MauiProgram.cs
Comment thread src/EventLogExpert/Adapters/Menu/MauiMenuActionService.cs Outdated
Comment thread src/EventLogExpert/Adapters/Menu/MauiMenuActionService.cs Outdated
Comment thread src/EventLogExpert/Adapters/Menu/MauiMenuActionService.cs Outdated
@jschick04 jschick04 force-pushed the jschick/modal-coordinator-pr4 branch from f471c0b to 059a03b Compare May 26, 2026 04:03
@jschick04 jschick04 requested a review from Copilot May 26, 2026 04:05
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Comment thread src/EventLogExpert/MauiProgram.cs
@jschick04 jschick04 force-pushed the jschick/modal-coordinator-pr4 branch from 059a03b to ab9f267 Compare May 26, 2026 04:18
@jschick04 jschick04 requested a review from Copilot May 26, 2026 04:18
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Comment thread src/EventLogExpert/Adapters/Menu/MauiMenuActionService.cs Outdated
@jschick04 jschick04 force-pushed the jschick/modal-coordinator-pr4 branch from ab9f267 to 97ac7ca Compare May 26, 2026 04:28
@jschick04 jschick04 requested a review from Copilot May 26, 2026 04:28
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.

@jschick04 jschick04 marked this pull request as ready for review May 26, 2026 04:42
@jschick04 jschick04 merged commit d67b33a into jschick/modal-coordinator-refactor May 26, 2026
2 checks passed
@jschick04 jschick04 deleted the jschick/modal-coordinator-pr4 branch May 26, 2026 04:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants