Filter library redesign: tags, SidebarTabs, import/export safety, and inline editing#571
Open
jschick04 wants to merge 20 commits into
mainmicrosoft/EventLogExpert:mainfrom
jschick/library-modal-redesignmicrosoft/EventLogExpert:jschick/library-modal-redesignCopy head branch name to clipboard
Open
Filter library redesign: tags, SidebarTabs, import/export safety, and inline editing#571jschick04 wants to merge 20 commits intomainmicrosoft/EventLogExpert:mainfrom jschick/library-modal-redesignmicrosoft/EventLogExpert:jschick/library-modal-redesignCopy head branch name to clipboard
jschick04 wants to merge 20 commits into
mainmicrosoft/EventLogExpert:mainfrom
jschick/library-modal-redesignmicrosoft/EventLogExpert:jschick/library-modal-redesignCopy head branch name to clipboard
Conversation
…g current keyboard contract (Up/Down/Left/Right/Home/End) and tabpanel display semantics as baseline before SidebarTabs<TTab> extraction
…abaseToolsModal with WAI-ARIA APG vertical contract (ArrowUp/Down/Home/End; ArrowLeft/Right no longer rotate), add ModalBodyLayout enum with CSS min-height fallback gated on BodyLayout=Flex, and opt DBTools/DebugLog/Settings/ReleaseNotes modals into the new layout contract
…apper and tolerant ImportPreflight with schemaVersion>1 unsupported-version handling, extract BuildFilterSetIdentityKey to FilterLibraryDedupKeys internal static with both Effects.cs call sites updated, and register via AddFilterLibraryExport method added to existing FilterLibraryServiceCollectionExtensions
…eight=80%, BodyLayout=Flex, and ImportExportClose footer wired through IFilePickerService and IFilterLibraryExportService, add LibraryEntrySection recursive sections-only hierarchy for Saved tab and per-row Rename plus per-row Export to LibraryEntryRow MoreMenu, re-key _rowRefs by (tab, id) for mount-always correctness, broaden file IO exception handling, and simplify import preflight to top-10 conflict-name list
…Library button opening FilterLibraryModal at default tab, rename AddFilter chevron menu Cached entry to Recent with matching method renames and FilterRow display-label mapping via ValueSelectItem child content, and preserve FilterMode.Cached enum for persistence compatibility
…eflight computation to prevent ArgumentException crash on duplicate-fingerprint existing entries, expose SidebarTabs.FocusActiveTabAsync and call it from FilterLibraryModal so sole-row deletions restore focus to the active tab button, and route FilterRow mode-switch announcement through GetFilterModeDisplayLabel so screen readers hear Recent instead of Cached
…ion to skip second occurrence rather than silently overwriting via UpdateEntry, and regenerate LibraryEntryId for ToAdd entries whose incoming Id collides with an existing entry's Id so store.Add does not crash with a swallowed unique-constraint violation
…ice Deserialize so legacy SavedFilterGroup[] exports from the pre-FilterLibrary FilterGroupModal no longer crash with System.NotSupportedException when LibraryEntry polymorphic deserialization rejects elements missing the Kind discriminator, by catching NotSupportedException and retrying as List<SavedFilterGroup> then converting each non-empty group to a LibraryEntryFilterSet mirroring LegacyFilterMigrator behavior, with two regression tests covering the conversion path and empty-group skipping
…TTab> extraction moved .sidebar-tabs-tabpanel rendering out of DBTools's CSS-isolation scope by wrapping the SidebarTabs invocation in a DBTools-owned div.db-tabs-container so the scope attribute reattaches at the wrapper level and rerouting every .sidebar-tabs-tabpanel ::deep selector in DatabaseToolsModal.razor.css to .db-tabs-container ::deep, restoring the two-column grid form layout, path-input-group flex behavior, elevation-warning styling, and responsive single-column collapse at 56rem
…me invocation for consistency with the other ModalBodyLayout.Flex modals DatabaseToolsModal DebugLogModal SettingsModal and ReleaseNotesModal which all omit the Title attribute, since the tablist already conveys the active section identity and the dialog title bar adds redundant chrome above the visual hierarchy
… badge, favorites-split, tags inline
…terEditor to per-row commit; clean comment-protocol violations
… ModalChrome; new --text-error token
…r dropdown contrast and inline control vertical rhythm
Contributor
There was a problem hiding this comment.
Pull request overview
Redesigns the Filter Library into a tag-centric, safer-to-migrate/import/export experience, while extracting reusable modal infrastructure (vertical WAI-ARIA SidebarTabs<TTab> and a shared FilterEditorCore) and tightening accessibility/validation behaviors in modal prompts.
Changes:
- Introduces
SidebarTabs<TTab>(vertical tablist + roving tabindex) and rewires DatabaseTools modal to use it. - Adds tag UX (TagPicker, inline chips, TagManagementPanel) plus runtime persistence/migrations (tags column, backslash-name migration).
- Extracts
FilterEditorCoreand extends inline modal prompt validation (validator + disabled accept + error aria wiring).
Reviewed changes
Copilot reviewed 107 out of 107 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/Unit/EventLogExpert.UI.Tests/Modal/SidebarTabsTests.cs | Unit tests for SidebarTabs behavior & ARIA. |
| tests/Unit/EventLogExpert.UI.Tests/Modal/SidebarTabsFocusContractTests.cs | Focus/tabindex contract tests for tabpanels. |
| tests/Unit/EventLogExpert.UI.Tests/Modal/SidebarTabsCascadeTests.cs | Cascading value propagation test through SidebarTabs. |
| tests/Unit/EventLogExpert.UI.Tests/Modal/ModalHeightInvariantTests.cs | Enforces Height= presence on flex-body modals. |
| tests/Unit/EventLogExpert.UI.Tests/Modal/ModalChromeValidateAsyncTests.cs | Inline prompt validation rendering/ARIA tests. |
| tests/Unit/EventLogExpert.UI.Tests/Modal/ModalBodyLayoutEnumStringificationTests.cs | Guards enum-to-string attribute literals. |
| tests/Unit/EventLogExpert.UI.Tests/Inputs/TagPickerTests.cs | TagPicker behavior + ARIA tests. |
| tests/Unit/EventLogExpert.UI.Tests/FilterPane/FilterPaneTests.cs | Updates expectations for “Recent” wording/behavior. |
| tests/Unit/EventLogExpert.UI.Tests/FilterLibrary/TagManagementPanelTests.cs | Tag rename/merge/delete panel tests. |
| tests/Unit/EventLogExpert.UI.Tests/FilterLibrary/LibrarySavedTabHeaderTests.cs | Tests “new saved filter” draft UI + validation. |
| tests/Unit/EventLogExpert.UI.Tests/FilterLibrary/LibraryFilterRowTests.cs | Wrapper row forwarding tests for library context. |
| tests/Unit/EventLogExpert.UI.Tests/FilterLibrary/LibraryEntryRowTests.cs | Library entry row tests (menu, tags, favorites). |
| tests/Unit/EventLogExpert.UI.Tests/FilterEditor/WrapperConformanceTests.cs | Snapshot tests for external parameter surfaces. |
| tests/Unit/EventLogExpert.UI.Tests/FilterEditor/FilterEditorCoreTests.cs | Tests extracted FilterEditorCore behavior. |
| tests/Unit/EventLogExpert.UI.Tests/DatabaseTools/DatabaseToolsModalTabbingTests.cs | Tabbing/roving focus tests for DB modal via tabs. |
| tests/Unit/EventLogExpert.UI.Tests/Alerts/PromptModalTests.cs | Prompt modal structure tests (divider). |
| tests/Unit/EventLogExpert.Runtime.Tests/FilterLibrary/LibraryEntryTagNormalizerTests.cs | Tag normalization + backslash migration unit tests. |
| tests/Unit/EventLogExpert.Runtime.Tests/FilterLibrary/LibraryEntryPolymorphicJsonTests.cs | JSON polymorphism + tags null/missing handling tests. |
| tests/Unit/EventLogExpert.Runtime.Tests/FilterLibrary/LegacyFilterMigratorTests.cs | Legacy migration behavior w/ backslash feature gating. |
| tests/Unit/EventLogExpert.Runtime.Tests/FilterLibrary/ImportPreflightCtorTests.cs | Import preflight constructor contract tests. |
| tests/Unit/EventLogExpert.Runtime.Tests/FilterLibrary/FilterLibraryDedupKeysTests.cs | Dedup key generation tests (incl tags). |
| tests/Unit/EventLogExpert.Runtime.Tests/FilterLibrary/FilterLibraryCommandsTests.cs | Command dispatch tests for tag ops. |
| tests/Unit/EventLogExpert.Runtime.Tests/FilterLibrary/BackslashNameMigratorTests.cs | Startup backslash migrator planning/idempotency tests. |
| tests/Unit/EventLogExpert.Runtime.Tests/Alerts/InlineAlertRequestTests.cs | InlineAlertRequest validation property tests. |
| tests/Integration/EventLogExpert.Runtime.IntegrationTests/FilterLibrary/FilterLibrarySqliteStoreTests.cs | Tags column persistence/migration integration coverage. |
| tests/Integration/EventLogExpert.Runtime.IntegrationTests/FilterLibrary/FilterLibraryMigrationIntegrationTests.cs | Effects wiring updated for backslash migrator dependency. |
| src/EventLogExpert/wwwroot/js/app.js | Adds scrollElementIntoView helper for inline expansion UX. |
| src/EventLogExpert/wwwroot/css/app.css | Global tokens/control sizing/icon alignment tweaks. |
| src/EventLogExpert/MauiProgram.cs | Registers export + backslash migration and ILegacyPreferences gating. |
| src/EventLogExpert.UI/wwwroot/Modal/SidebarTabs.js | JS preventDefault shim for vertical tab keys. |
| src/EventLogExpert.UI/wwwroot/DatabaseTools/DatabaseToolsModal.js | Removes DBTools-specific tab shim (migrated to SidebarTabs). |
| src/EventLogExpert.UI/Update/ReleaseNotesModal.razor | Switches to BodyLayout="Flex" for height behavior. |
| src/EventLogExpert.UI/Settings/SettingsModal.razor | Switches to BodyLayout="Flex" for height behavior. |
| src/EventLogExpert.UI/Modal/SidebarTabs.razor.css | Styling for new sidebar/vertical tabs layout. |
| src/EventLogExpert.UI/Modal/SidebarTabs.razor.cs | New reusable vertical tabs component logic/JS wiring. |
| src/EventLogExpert.UI/Modal/SidebarTabs.razor | New reusable vertical tabs markup/ARIA. |
| src/EventLogExpert.UI/Modal/ModalChrome.razor.css | Flex-body layout rules + inline validation error styling. |
| src/EventLogExpert.UI/Modal/ModalChrome.razor.cs | Adds BodyLayout and validation evaluation for prompts. |
| src/EventLogExpert.UI/Modal/ModalChrome.razor | Emits data-body-layout, prompt aria-invalid/error, disables accept. |
| src/EventLogExpert.UI/Modal/ModalBodyLayout.cs | New enum for chrome body layout mode. |
| src/EventLogExpert.UI/Inputs/Toggle.razor.css | Aligns toggle sizing to shared control height token. |
| src/EventLogExpert.UI/Inputs/TagPicker.razor.css | New TagPicker component styling. |
| src/EventLogExpert.UI/Inputs/TagPicker.razor.cs | New TagPicker component logic (normalize, dropdown, keyboard). |
| src/EventLogExpert.UI/Inputs/TagPicker.razor | New TagPicker markup/ARIA combobox + chips. |
| src/EventLogExpert.UI/FilterPane/FilterPaneAnnouncements.cs | Renames “Cached” announcement to “Recent”. |
| src/EventLogExpert.UI/FilterPane/FilterPane.razor.css | Adds filter set option row styling/ellipsis. |
| src/EventLogExpert.UI/FilterPane/FilterPane.razor.cs | “Recent” menu item + richer filter set labels + library open action. |
| src/EventLogExpert.UI/FilterPane/FilterPane.razor | Updates tooltips/buttons and filter set select row markup. |
| src/EventLogExpert.UI/FilterLibrary/TagManagementPanel.razor.css | Styling for tag management panel. |
| src/EventLogExpert.UI/FilterLibrary/TagManagementPanel.razor.cs | Tag rename/merge/delete behaviors + announcements/commands. |
| src/EventLogExpert.UI/FilterLibrary/TagManagementPanel.razor | Tag management panel UI/ARIA. |
| src/EventLogExpert.UI/FilterLibrary/LibrarySavedTabHeader.razor.css | Styles for “new saved filter” draft panel. |
| src/EventLogExpert.UI/FilterLibrary/LibrarySavedTabHeader.razor.cs | Draft state, validation, tag picker integration, command dispatch. |
| src/EventLogExpert.UI/FilterLibrary/LibrarySavedTabHeader.razor | Draft UI markup incl TagPicker. |
| src/EventLogExpert.UI/FilterLibrary/LibraryFilterRow.razor.cs | Thin wrapper over shared FilterEditorCore for library usage. |
| src/EventLogExpert.UI/FilterLibrary/LibraryFilterRow.razor | Renders FilterEditorCore with library callbacks. |
| src/EventLogExpert.UI/FilterLibrary/LibraryEntryRow.razor | Adds inline tags UI/editing + filter-set expand + menu/favorite changes. |
| src/EventLogExpert.UI/FilterLibrary/LibraryEntryFilterEditor.razor.css | Styles for inline filter editor within a filter set. |
| src/EventLogExpert.UI/FilterLibrary/LibraryEntryFilterEditor.razor.cs | Inline filter-set editor logic (add/remove/edit filters). |
| src/EventLogExpert.UI/FilterLibrary/LibraryEntryFilterEditor.razor | Inline filter-set editor markup. |
| src/EventLogExpert.UI/FilterLibrary/FilterLibraryModal.razor.css | Reworks tag filter chip bar styling. |
| src/EventLogExpert.UI/FilterEditor/FilterRow.razor.css | Removes legacy FilterRow-specific CSS (moved to core). |
| src/EventLogExpert.UI/FilterEditor/FilterRow.razor | Replaces old editor implementation with FilterEditorCore. |
| src/EventLogExpert.UI/FilterEditor/FilterEditorCore.razor.css | New shared editor core CSS. |
| src/EventLogExpert.UI/FilterEditor/FilterEditorCore.razor.cs | New shared editor core logic (mode switching, validation, UX). |
| src/EventLogExpert.UI/FilterEditor/FilterEditorCore.razor | New shared editor core markup (basic/advanced/recent modes). |
| src/EventLogExpert.UI/FilterEditor/Editing/FilterEditPanel.razor.css | Layout tweaks for consistent control alignment. |
| src/EventLogExpert.UI/FilterEditor/CachedFilterOption.cs | Shared DTO for recent/cached dropdown options. |
| src/EventLogExpert.UI/DebugLog/DebugLogModal.razor | Switches to BodyLayout="Flex". |
| src/EventLogExpert.UI/DatabaseTools/DatabaseToolsModal.razor.css | Updates scoping to reach into SidebarTabs subtree. |
| src/EventLogExpert.UI/DatabaseTools/DatabaseToolsModal.razor.cs | Removes bespoke tab JS/logic; relies on SidebarTabs. |
| src/EventLogExpert.UI/DatabaseTools/DatabaseToolsModal.razor | Uses SidebarTabs and sets BodyLayout="Flex". |
| src/EventLogExpert.UI/Alerts/PromptModal.razor.css | Styles divider inserted between message and input. |
| src/EventLogExpert.UI/Alerts/PromptModal.razor | Adds divider, minor attribute ordering change. |
| src/EventLogExpert.Runtime/FilterLibrary/RenameTagAction.cs | Adds action for tag rename. |
| src/EventLogExpert.Runtime/FilterLibrary/DeleteTagAction.cs | Adds action for tag delete. |
| src/EventLogExpert.Runtime/FilterLibrary/NoOpLegacyFilterMigrator.cs | Removes docblock; keeps inert implementation. |
| src/EventLogExpert.Runtime/FilterLibrary/NoOpBackslashNameMigrator.cs | No-op migrator for disabled feature. |
| src/EventLogExpert.Runtime/FilterLibrary/LibraryEntryTagNormalizer.cs | Adds tag normalization + backslash-to-tags migration + JSON converter. |
| src/EventLogExpert.Runtime/FilterLibrary/LibraryEntry.cs | Adds Tags property w/ JSON converter. |
| src/EventLogExpert.Runtime/FilterLibrary/LegacyMigrationFeature.cs | Adds test override + stages deletion contract updates. |
| src/EventLogExpert.Runtime/FilterLibrary/LegacyFilterMigrator.cs | Adds backslash gating behavior for group names. |
| src/EventLogExpert.Runtime/FilterLibrary/BackslashNameMigrator.cs | Adds startup migration plan for backslash-named entries. |
| src/EventLogExpert.Runtime/FilterLibrary/BackslashMigrationFeature.cs | Adds feature gate + test override for backslash migration. |
| src/EventLogExpert.Runtime/FilterLibrary/ImportPreflight.cs | Adds richer import preflight model incl blocked state. |
| src/EventLogExpert.Runtime/FilterLibrary/IFilterLibraryExportService.cs | Adds import/export service contract. |
| src/EventLogExpert.Runtime/FilterLibrary/IFilterLibraryCommands.cs | Adds RenameTag/DeleteTag commands. |
| src/EventLogExpert.Runtime/FilterLibrary/IBackslashNameMigrator.cs | Adds migrator interface and result record. |
| src/EventLogExpert.Runtime/FilterLibrary/FilterLibrarySqliteStore.cs | Adds tags column persistence + null-guards. |
| src/EventLogExpert.Runtime/FilterLibrary/FilterLibraryServiceCollectionExtensions.cs | Adds export + backslash migrator registrations; feature-gated legacy migrator. |
| src/EventLogExpert.Runtime/FilterLibrary/FilterLibraryDedupKeys.cs | Centralizes dedup key generation incl tags. |
| src/EventLogExpert.Runtime/FilterLibrary/FilterLibraryCommands.cs | Dispatches new tag actions. |
| src/EventLogExpert.Runtime/FilterLibrary/Effects.cs | Adds tag rename/delete effects + backslash startup migration wiring. |
| src/EventLogExpert.Runtime/EventLogExpert.Runtime.csproj | Adds InternalsVisibleTo for DynamicProxyGenAssembly2. |
| src/EventLogExpert.Runtime/Alerts/InlineAlertRequest.cs | Adds Validate function for inline prompt validation. |
| src/EventLogExpert.Runtime/Alerts/IAlertDialogService.cs | Adds prompt overload accepting validation callback. |
| src/EventLogExpert.Runtime/Alerts/AlertDialogService.cs | Pipes validation into inline prompt requests. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
207d159 to
e1226bf
Compare
e1226bf to
e8c09dc
Compare
28df529 to
33131fc
Compare
Contributor
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 108 out of 108 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (1)
src/EventLogExpert.Runtime/Alerts/AlertDialogService.cs:79
- The new DisplayPrompt(validate) overload applies validation only when an inline-alert host modal is active. In the standalone PromptModal fallback path, the validator is silently ignored, so callers can receive invalid input when no host modal is present (e.g., app startup / activation flows). Consider threading the validator through to PromptModal (e.g., pass it in the parameters dictionary and have PromptModal/ModalChrome disable OK + render an error), or otherwise enforce validation consistently across both paths.
if (!_modalCoordinator.TryGetInlineAlertHost(out var host))
{
return await _openStandalonePrompt(new Dictionary<string, object?>
{
["Title"] = title,
["Message"] = message,
["InitialValue"] = initialValue ?? string.Empty,
});
}
33131fc to
6eb8c78
Compare
6eb8c78 to
52af226
Compare
52af226 to
2b0c8b9
Compare
2b0c8b9 to
2a2111b
Compare
2a2111b to
e20e15b
Compare
e20e15b to
4454471
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Redesigns the Filter Library into a 3-tab modal (Saved / Favorites / Previously Used) with tag-based organization, inline filter editing, and safer import/export. Extracts a reusable
SidebarTabs<TTab>WAI-ARIA vertical tablist and removes the legacy FilterCache/FilterGroup domain behind a feature-flagged migration.Key changes
FilterLibraryModal3-tabSidebarTabs<TTab>layout; per-entry overflow menu, favorites split, inlineLibraryFilterRowediting (FilterEditorCoreextracted, shared withFilterPane).SavedFilterGroup[]fallback, and malformed-input safety.FilterPane/FilterRowto FilterLibrary, gatedLegacyFilterMigrator.Review & testing