Filter slice rework: extract Filtering library, slice UI by feature, migrate to command facades#527
Merged
Merged
Conversation
…tLog/FilterPane cycle
Extract LogTablePane.BuildActiveHighlightFilters to a dedicated HighlightFilterSelector that takes the full FilterPaneState. The selector intentionally consults only Filters, leaving IsEnabled (the Ctrl+H 'Show All Events' toggle) untouched, so highlight cues survive when the visibility-filter pipeline is suspended. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…cking filter generation
…econd LogCloseTimeout
…h IFilterCacheCommands
…ng renamed actions
…orphan reload reopen
…atching renamed action
…ervices moved from MauiProgram
… per-iteration in reopen loop
…ssolving Modals and flattening Filters Common
… test projects and consumer references
…ving MAUI head internal Layout and Sections namespaces
…h DI-convention namespaces
…uplicate filter-change test
…s, MergeSorted, MatchesFilters, MatchesDateFilter, and AddFilterGroup
NikTilton
approved these changes
May 18, 2026
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
Foundational rework of the filter system across the EventLogExpert solution. Three primary outcomes:
Filtering library extraction. New
EventLogExpert.Filteringlibrary replaces the embedded UI-coupled filter implementation with a hand-rolled parse/lower/emit pipeline (Dynamic.LINQ dropped from production). Domain types (Filter,BasicFilter,SavedFilter,FilterComparison, etc.) live in a clean-architecture inner ring with no UI / Fluxor / MAUI dependencies. Folder topology:Basic/,Common/,EventData/,Parsing/,Lowering/,Emit/,Runtime/,Persistence/,Drafts/,DependencyInjection/.UI slice migration to command facades. Per-slice Fluxor action dispatch reorganized behind host-facing command facades (
IEventLogCommands,IFilterPaneCommands,IFilterGroupCommands,ILogTableCommands,IFilterCacheCommands). Internal actions / reducers / effects demoted tointernal sealed, with a singleRegisterUiLibrary()composition-root extension as the public DI entry point.InternalsVisibleTofromEventLogExpert.UIto the MAUI head dropped (only test assemblies retain IVT).Per-slice preference ports + service relocations. Six per-slice
I*PreferencesProviderinterfaces (replacing one monolithicIPreferencesProvider); 16 application/update services moved fromMauiProgram.csintoRegisterUiLibrary()so the UI library owns its service registrations.Scope (by area)
Filtering library (
EventLogExpert.Filtering)FilterParser(Parsing/) + ASTFilterCompiler(FilterCompiler.cs) + closure emitter (Emit/Emitter.cs) + AND-chain UserId peephole (Lowering/); Dynamic.LINQ removed from production paths.BasicFilterdecomposer +FilterComparisoncascade (renamed fromBasicFilterCondition).EventFilterrenamed toFilter(runtime type) with the legacy name reserved for the persisted shape.EventLogDataPOCO hoisted intoEventLogExpert.Eventing(cross-asm consumer);EventPropertyValuesCacherenamed fromEventPropertyItemsCache.AddEventLogFiltering()registrar (currently a no-op for future expansion;IFilterServicestays in the UI layer due to itsEventLogData/EventLogIdcycle with the EventLog Fluxor slice).Basic//Common//EventData//Parsing//Runtime/per VSA;BasicFilterDecomposerdemoted tointernal.UI slice migration (
EventLogExpert.UI)IEventLogCommands(open/close/reload),IFilterPaneCommands(apply/clear),IFilterGroupCommands(CRUD + import/export),ILogTableCommands(columns/highlights),IFilterCacheCommands(recent/favorite filters). Each slice''s actions demoted tointernal sealed.DebugLogService,SettingsService, etc.) moved behindRegisterUiLibrary;DatabaseService+DebugLogServicefurther demoted with IVT grant toEventLogExpert.UI.IntegrationTestsfor the integration tests that need them.ILogReloadCoordinatorregistered as an interface over the Fluxor-managedEffectsinstance (the host bridge betweenDatabaseServiceand the EventLog slice without exposingEffectsdirectly).IEventLogPreferencesProvider,IFilterPanePreferencesProvider,IFilterGroupPreferencesProvider,ILogTablePreferencesProvider,IFilterCachePreferencesProvider,IDetailsPanePreferencesProvider. MAUI head''sPreferencesProviderimplements all six.Naming polish (slice-aware action / property names)
FilterCache.*CompletedAction->*SuccessAction(matches the success-path terminology used elsewhere).EventLog.SetFiltersAction->ApplyFilterAction(matches intent: this is a user-initiated apply, not a generic set).EventLog.AddEventBufferedAction->EventBufferedAction(state-notification, not user intent).EventPropertyItems->EventPropertyValues(the cache stores values, not items).FilterGroupactions disambiguated fromFilterPanesiblings:SetGroupFilterAction,RemoveGroupFilterAction,ToggleGroupFilterExcludedAction, etc. (theGroupqualifier matters because both slices have parallelSet*Filter*actions).FilterLoadingslice renamed toFilterProgress(slice folder + namespace + state + action).Concurrency hardening (EventLog
HandleApplyFilter)HandleApplyFilterintoReloadLogsWithXmlAsync(close-and-reopen-with-XML path) andApplyFilterAndPublishAsync(filter-only path); both bump_filterGenerationso a newer dispatch supersedes the older._closeAllGenerationcounter distinct from_filterGeneration:HandleCloseAllbumps_closeAllGeneration, andReloadLogsWithXmlAsyncchecks ONLY that counter before its reopen loop -- a racing newerApplyFilter(which only bumps_filterGeneration) must NOT cancel an in-flight reload._closeAllGenerationsnapshot captured BEFORE readingActiveLogs(avoids TOCTOU where a CloseAll between the read and capture would pin a stale snapshot to the new generation).CloseLogActionfor already-reopened logs as cleanup + clears_pendingSelectionRestoreentries to prevent stale selection restore on a later manual reopen.HandleCloseAllnow takes the requiredIDispatcherparameter (Fluxor 6.9.0 mandates this signature for[EffectMethod(typeof(...))]-- a runtime registration error otherwise).FilterLoading/SetFilters/FilterModelTestsidentifiers updated.Review-cycle fixes (14 commits across 5 GitHub Copilot review rounds)
var Filter = new Filter(...)) renamed to camelCase acrossEffectsTests.cs(10 sites) andFilterExtensionsTests.cs(6 sites).EffectsTests,FilterGroupStoreTests,EventLogStoreTests,FilterProgressStoreTests).using EventLogExpert.Filtering;directives removed fromDebugLogProjection,IFilterService,FilterService; redundant self-namespaceusingremoved fromFilterParser.LoadGroupsSuccessAction,LoadColumnsCompletedAction,SetFilterProgressAction);FilterProgress.Reducersclass also demoted to internal (CS0051 cascade from the action demotion).[Inject] private IDispatcher Dispatcherproperties removed after facade migration (FilterGroupModal,FilterGroup,FilterRow,LogTabBar,LogTablePane).UiServiceCollectionExtensionsTests) extended from 6 to 23InlineDataentries covering all command facades, UI capabilities, application services, and update/deployment services moved intoRegisterUiLibrary.AddEventLogFilteringregistrar gainedArgumentNullException.ThrowIfNull(services)+ standalone XML doc summary (was referencing planning notationD6/D9).FilterModelTestsclass inSavedFilterTests.csrenamed toSavedFilterTeststo match file name.Decision log (key calls made along the way)
IFilterServicestays in the UI layer. The DAG-coherence audit surfaced cycle Set CODEOWNERS and update docs #2:IFilterServicereferencesEventLogData/EventLogId, both owned by the EventLog Fluxor slice and constraint-locked to UI. Filtering library (clean-arch inner ring) cannot reach into UI types; FilterService stays where its consumers are.Basic/(notFilters/) as the runtime filter folder name. Avoids a three-way collision with the upcoming UI restructure''s two.Filtersnamespaces.Common/<Domain>/over flatCommon/. Per VSA, cross-cutting types live in domain-themed sub-folders (Common/Channels/,Common/Events/), not in a flat dump.EventData/(notEvents/) as the filter-data slice name. Avoids collision withEventing.Common.Events.BasicFilterDecomposerisinternal. Only consumed within the Filtering library; demoted post-reorg (one of two viable demotions found by the audit).TODO: whenHandleApplyFiltertriggers an XML-reload for some logs, logs that already had XML loaded keep their previousDisplayedEventsuntil another event arrives. Address in a follow-up PR -- narrow enough that it does not gate this rework.Verification
dotnet build EventLogExpert.slnx: 0 warnings, 0 errors.dotnet test EventLogExpert.slnx: 2,632 tests pass (2 skipped -- pre-existing platform-gated Eventing integration tests). Breakdown:EventLogExpert.Eventing.Tests: 288EventLogExpert.Eventing.IntegrationTests: 334 + 2 skippedEventLogExpert.Filtering.Tests: 603EventLogExpert.Components.Tests: 150EventLogExpert.EventDbTool.Tests: 8EventLogExpert.EventDbTool.IntegrationTests: 38EventLogExpert.UI.Tests: 1087EventLogExpert.UI.IntegrationTests: 124Notes for reviewer
EventLogExpert.UI->EventLogExpert.UI.Testsand ->EventLogExpert.UI.IntegrationTestsIVT grants remain (tests need internal access). The MAUI head''s IVT grant fromEventLogExpert.UIwas dropped.Testsproject with IVT grant; no cross-asm internals leakage to UI.692f802) is the validated one with 3 new race-condition unit tests.