Skip to content

Add FilterLibraryModal 3-tab redesign with LibraryEntryRow overflow menu and ARIA focus cascade#564

Merged
NikTilton merged 1 commit into
mainfrom
jschick/library-modal-ui
Jun 3, 2026
Merged

Add FilterLibraryModal 3-tab redesign with LibraryEntryRow overflow menu and ARIA focus cascade#564
NikTilton merged 1 commit into
mainfrom
jschick/library-modal-ui

Conversation

@jschick04
Copy link
Copy Markdown
Collaborator

Redesigns the FilterLibraryModal as a 3-tab (Saved / Favorites / Previously Used) layout with an LibraryEntryRow that has Apply/Favorite/More overflow menu, ARIA tablist roving focus, and a strict-priority focus restoration cascade after row removal.

Scope

  • New public types: LibraryTab (enum), FavoriteToggleIntent + AddToPresetIntent (records with non-null param validation on AddToPresetIntent.Filter)
  • New wwwroot/FilterLibrary/FilterLibraryModal.js keydown shim (idempotent attach/detach; HANDLED_KEYS = ArrowLeft/ArrowRight/Home/End for role=tab only)
  • FilterLibraryModal.razor* rewrite: 3 tabs always in DOM with display:none for inactive (preserves aria-controls integrity); active tabpanel tabindex=0 only when empty; strict-priority focus cascade (target-row -> tab-button -> active-tab fallback within same render); @key="entry.Id" for ref stability; OnDialogClosedByUser wired for Esc/backdrop dismiss
  • LibraryEntryRow.razor* rewrite: icon + name + status badge + Apply/Favorite/More buttons; 7 EventCallback params (OnApply/OnReplace/OnDelete/OnToggleFavorite/OnSaveToLibrary/OnAddToPreset/OnRequestPendingFocus); IMenuService.StateChanged per-row subscription; IAsyncDisposable; confirm dialogs for destructive actions; BuildMoreMenu() with SubMenu for Add-to-preset; JS bounding-rect for menu anchoring
  • ElementFocus.TrySafelyAsync - new ValueTask<bool> helper parallel to existing SafelyAsync for cascade-on-failure semantics

Spec invariants

  • Previously Used = LastUsedUtc != null, ordered desc, top 50
  • IsFavorite=true => LastUsedUtc=null (favorites leave Previously Used)
  • Favoriting promotes Origin=UserSaved; once UserSaved stays UserSaved
  • Result: a favorited UserSaved entry appears in BOTH Saved AND Favorites tabs

Tests

Pre-PR review (Section 2D 5-model panel)

  • Round 1: 3 NEEDS_ANOTHER + 2 READY; 2 convergent MAJOR findings (Esc/backdrop dismiss wire-up missing; JS keydown shim attach timing) + 1 MAJOR (focus-cascade tests gap) + 5 minor
  • Round 2: unanimous READY_TO_IMPLEMENT (5/5) after 1 fix iteration
  • All 8 findings addressed via amend; round 2 verified fixes are correct + complete + no regressions

Follow-up commits

  • F: Rewire FilterPane / FilterRow / MainPage / MauiMenuActionService / _Imports to use the new modal+row API; drop FilterCache/FilterGroup injections
  • G: Delete legacy FilterCache + FilterGroup runtime + UI domains + preferences adapters + modal launchers; grep-gate verification

Copilot AI review requested due to automatic review settings June 3, 2026 01:12
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

This PR redesigns the Filter Library modal UI into a 3-tab (Saved / Favorites / Previously Used) layout with per-row actions (Apply / Favorite / overflow “More” menu), adds a JS keydown shim to suppress native tablist key behavior, and implements a strict focus-restoration cascade for accessibility after row removal.

Changes:

  • Reworks FilterLibraryModal into an ARIA tablist + 3 persistent tabpanels (inactive panels hidden via display:none) with roving-focus keyboard handling and focus restoration after removal.
  • Rewrites LibraryEntryRow to include status/kind visuals, favorite toggling semantics, and an overflow menu anchored via JS bounding-rect interop.
  • Adds new UI-level types (LibraryTab, intents) and extends unit tests to cover the new UI behavior and invariants.

Reviewed changes

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

Show a summary per file
File Description
tests/Unit/EventLogExpert.UI.Tests/FilterLibrary/LibraryEntryRowTests.cs Expands unit coverage for row rendering, menu contents, confirm flows, and intent callbacks.
tests/Unit/EventLogExpert.UI.Tests/FilterLibrary/FilterLibraryModalTests.cs Adds tests for 3-tab projections, sorting, empty states, and tab keyboard navigation.
src/EventLogExpert.UI/wwwroot/FilterLibrary/FilterLibraryModal.js Adds a keydown shim to prevent default browser behavior for handled tablist keys.
src/EventLogExpert.UI/Focus/ElementFocus.cs Adds TrySafelyAsync for focus-attempt semantics needed by the focus cascade.
src/EventLogExpert.UI/FilterLibrary/LibraryTab.cs Introduces LibraryTab enum for Saved/Favorites/PreviouslyUsed.
src/EventLogExpert.UI/FilterLibrary/LibraryEntryRow.razor.css Updates row styling for the new icon/name/status/actions layout.
src/EventLogExpert.UI/FilterLibrary/LibraryEntryRow.razor.cs Implements row behavior: confirm dialogs, overflow menu building, announcements, menu anchoring, and menu service subscription.
src/EventLogExpert.UI/FilterLibrary/LibraryEntryRow.razor Updates markup for kind icon, name/details, status badge, and action buttons with ARIA attributes.
src/EventLogExpert.UI/FilterLibrary/FilterLibraryModal.razor.css Adds styles for tab buttons, panels, and improved loading/error/empty states.
src/EventLogExpert.UI/FilterLibrary/FilterLibraryModal.razor.cs Implements tab projections, keyboard navigation, JS attach/detach, and focus restoration cascade logic.
src/EventLogExpert.UI/FilterLibrary/FilterLibraryModal.razor Replaces list rendering with ARIA tablist/tabpanels and wires new row API.
src/EventLogExpert.UI/FilterLibrary/FavoriteToggleIntent.cs Adds intent record for favorite toggle callbacks.
src/EventLogExpert.UI/FilterLibrary/AddToPresetIntent.cs Adds intent record for “add filter to preset” actions with non-null filter validation.
src/EventLogExpert.UI/_Imports.razor Adds using directives for new FilterLibrary namespaces/types.
.github/pr-quality-gate/audits/last.md Updates PR-quality-gate audit snapshot for this change set.

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

Comment thread tests/Unit/EventLogExpert.UI.Tests/FilterLibrary/LibraryEntryRowTests.cs Outdated
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 14 out of 14 changed files in this pull request and generated 1 comment.

Comment thread src/EventLogExpert.UI/FilterLibrary/FilterLibraryModal.razor.cs
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 14 out of 14 changed files in this pull request and generated 1 comment.

Comment thread src/EventLogExpert.UI/FilterLibrary/FilterLibraryModal.razor.cs
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 14 out of 14 changed files in this pull request and generated 1 comment.

Comment thread src/EventLogExpert.UI/FilterLibrary/AddToPresetIntent.cs
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 14 out of 14 changed files in this pull request and generated 1 comment.

Comment thread tests/Unit/EventLogExpert.UI.Tests/FilterLibrary/LibraryEntryRowTests.cs Outdated
@jschick04 jschick04 force-pushed the jschick/library-modal-ui branch from 7f82be6 to e5e3397 Compare June 3, 2026 02:33
@jschick04 jschick04 requested a review from Copilot June 3, 2026 02:33
@jschick04 jschick04 force-pushed the jschick/library-modal-ui branch from e5e3397 to 7757674 Compare June 3, 2026 02: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 15 out of 15 changed files in this pull request and generated no new comments.

@jschick04 jschick04 marked this pull request as ready for review June 3, 2026 02:38
@jschick04 jschick04 requested a review from a team as a code owner June 3, 2026 02:38
@jschick04 jschick04 force-pushed the jschick/library-modal-ui branch from 7757674 to 35ed5a3 Compare June 3, 2026 02:39
@jschick04 jschick04 requested a review from Copilot June 3, 2026 03:04
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 14 out of 14 changed files in this pull request and generated 1 comment.

Comment thread src/EventLogExpert.UI/FilterLibrary/LibraryEntryRow.razor Outdated
@jschick04 jschick04 force-pushed the jschick/library-modal-ui branch from 35ed5a3 to d7f0157 Compare June 3, 2026 04:46
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.

3 participants