Skip to content

Make bulk tag updates atomic, prune unloadable library rows, and reconcile modal row refs#572

Draft
jschick04 wants to merge 1 commit into
jschick/library-modal-redesignfrom
jschick/library-modal-followups
Draft

Make bulk tag updates atomic, prune unloadable library rows, and reconcile modal row refs#572
jschick04 wants to merge 1 commit into
jschick/library-modal-redesignfrom
jschick/library-modal-followups

Conversation

@jschick04
Copy link
Copy Markdown
Collaborator

Stacked on jschick/library-modal-redesign (#571) — implements five follow-ups deferred from that PR's review, plus the safety/resilience refinements surfaced during this PR's own review.

Changes

Atomic, resilient bulk tag rename/delete. Tag rename and delete now persist all affected entries in a single transaction via a new IFilterLibraryStore.UpdateRange, instead of per-entry writes. The effect dispatches success only for rows actually written, reloads the library if any row was already gone or the batch failed, and announces the affected-entry count (e.g. "Renamed tag 'X' to 'Y' in 3 entries") — the screen-reader announcement now comes from the effect with the real count. If the persist fails, a failure announcement is made and the tag-filter selection is rolled back to its pre-operation state, so a failed operation never leaves the list filtered to nothing.

Clean up unloadable rows on load, with a safety net. LoadAll deletes library rows of a known kind whose payload can't be deserialized (logged), so a single corrupt row no longer blocks the rest of the library. Rows of an unknown kind are kept untouched as forward-version data — the kind is checked before any other column is parsed. If an unusually large share of rows are unreadable (a sign of a version mismatch rather than isolated corruption), deletion is withheld entirely and a persistent banner alerts the user, so a systemic problem can't silently delete the whole library.

Reconcile stale row references. LibraryEntryRow notifies the modal when it's disposed, and the modal reconciles its row-reference map against the live entries, so stale references don't accumulate after entries are removed.

Tests

  • Runtime unit: 1194 passing
  • UI unit: 609 passing
  • Runtime integration (containerized): 174 passing

New coverage includes atomic/partial-update and failure-rollback paths, unloadable- and unknown-kind row handling, the systemic-corruption circuit breaker, the dispose-notification hook, scroll-interop disconnect handling, per-tab DOM id uniqueness, and tag-filter resilience.

Follow-up

The filter pane has a sibling row-reference/prune pattern that will be addressed in a separate change.

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 builds on the filter-library modal redesign to harden tag bulk operations, improve SQLite store resilience when encountering corrupt/unrecognized rows, and prevent stale UI row references from accumulating in the modal.

Changes:

  • Make bulk tag rename/delete persist via a single IFilterLibraryStore.UpdateRange(...) transaction and announce affected-entry counts from the effect, with reload + rollback signaling on failure.
  • Prune unloadable known-kind SQLite rows during LoadAll() while keeping unknown kinds as forward-version data, plus a systemic-corruption circuit breaker that reports a persistent banner instead of deleting.
  • Reconcile modal row refs by notifying the modal on LibraryEntryRow disposal and pruning row refs against the current entry set.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/Unit/EventLogExpert.UI.Tests/FilterLibrary/LibraryEntryRowTests.cs Adds coverage for row disposal notifications and JS interop disconnect handling during tag edit.
tests/Unit/EventLogExpert.UI.Tests/FilterLibrary/FilterLibraryModalTests.cs Adds coverage for tag-filter resilience, rollback on rename failure, and per-tabpanel DOM id uniqueness.
tests/Unit/EventLogExpert.Runtime.Tests/FilterLibrary/FilterLibraryEffectsTests.cs Updates tests for atomic tag updates via UpdateRange, success/failure announcements, reload behavior, and failure action dispatching.
tests/Integration/EventLogExpert.Runtime.IntegrationTests/FilterLibrary/FilterLibrarySqliteStoreTests.cs Adds integration coverage for unloadable-row deletion rules, systemic corruption circuit breaker + banner, unknown-kind retention, and UpdateRange.
tests/Integration/EventLogExpert.Runtime.IntegrationTests/FilterLibrary/FilterLibraryMigrationIntegrationTests.cs Updates effect construction and store wrapper to include announcement service and UpdateRange.
src/EventLogExpert.UI/FilterLibrary/TagManagementPanel.razor.cs Moves announcements out of the panel and reorders callbacks to allow modal to snapshot optimistic selection before dispatching commands.
src/EventLogExpert.UI/FilterLibrary/LibraryEntryRow.razor.cs Adds OnDisposed callback and swallows JSDisconnectedException during scroll-into-view in tag edit mode.
src/EventLogExpert.UI/FilterLibrary/FilterLibraryModal.razor.cs Adds optimistic tag-selection snapshot/revert on bulk update failure; reconciles stale row refs; filters stale selected tags from affecting tag filtering.
src/EventLogExpert.UI/FilterLibrary/FilterLibraryModal.razor Wires LibraryEntryRow.OnDisposed to modal handler.
src/EventLogExpert.Runtime/FilterLibrary/TagBulkUpdateFailedAction.cs Adds explicit action to signal bulk tag update failure to the UI for rollback.
src/EventLogExpert.Runtime/FilterLibrary/IFilterLibraryStore.cs Adds UpdateRange(...) API for atomic bulk persistence.
src/EventLogExpert.Runtime/FilterLibrary/FilterLibrarySqliteStore.cs Implements UpdateRange transactionally; deletes unloadable known-kind rows on load with systemic-corruption guard and banner reporting; keeps unknown kinds untouched.
src/EventLogExpert.Runtime/FilterLibrary/FilterLibraryServiceCollectionExtensions.cs Wires optional IErrorBannerService into the SQLite store.
src/EventLogExpert.Runtime/FilterLibrary/Effects.cs Refactors tag rename/delete to use bulk persistence, reload behavior, failure signaling, and effect-driven announcements.

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

Comment thread src/EventLogExpert.UI/FilterLibrary/FilterLibraryModal.razor.cs Outdated
Comment thread src/EventLogExpert.UI/FilterLibrary/FilterLibraryModal.razor.cs Outdated
Comment thread src/EventLogExpert.UI/FilterLibrary/FilterLibraryModal.razor.cs Outdated
@jschick04 jschick04 force-pushed the jschick/library-modal-followups branch from 1819edd to a7689c3 Compare June 6, 2026 23:20
@jschick04
Copy link
Copy Markdown
Collaborator Author

Addressed the performance feedback (force-pushed a7689c3a):

  • SelectedTagsInLibrary(tab) recomputed per entryFavoriteEntries/PreviouslyUsedEntries/SavedEntries are now block-bodied and compute the selected-tags list once per property, reused in the .Where(...) predicate (was O(N²), and it rebuilt AllLibraryTags on every call).

Also folded in two related items from review:

  • FilterPane row-ref prune parityFilterRow now notifies the pane on dispose (mirrors the modal's reconcile + dispose-hook).
  • More conservative systemic-corruption circuit breaker — withholds deletion at >= half unloadable rows (instead of strict majority), so an even split where one kind's payload breaks isn't half-deleted.

Tests: Runtime unit 1194, UI 611, integration 175 — all green.

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 20 out of 20 changed files in this pull request and generated 1 comment.

Comment thread src/EventLogExpert.Runtime/FilterLibrary/IFilterLibraryStore.cs
@jschick04 jschick04 force-pushed the jschick/library-modal-followups branch from a7689c3 to d82481d Compare June 6, 2026 23:41
@jschick04 jschick04 requested a review from Copilot June 6, 2026 23:43
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 20 out of 20 changed files in this pull request and generated 2 comments.

Comment thread src/EventLogExpert.Runtime/FilterLibrary/FilterLibrarySqliteStore.cs Outdated
Comment thread src/EventLogExpert.Runtime/FilterLibrary/FilterLibrarySqliteStore.cs Outdated
@jschick04 jschick04 force-pushed the jschick/library-modal-followups branch from d82481d to 6666367 Compare June 7, 2026 00:02
@jschick04 jschick04 requested a review from Copilot June 7, 2026 00:08
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 20 out of 20 changed files in this pull request and generated 1 comment.

Comment thread src/EventLogExpert.Runtime/FilterLibrary/FilterLibrarySqliteStore.cs Outdated
@jschick04 jschick04 force-pushed the jschick/library-modal-followups branch from 6666367 to 84af813 Compare June 7, 2026 00:47
@jschick04 jschick04 requested a review from Copilot June 7, 2026 00:50
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 20 out of 20 changed files in this pull request and generated 1 comment.

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

Comment thread src/EventLogExpert.UI/FilterLibrary/FilterLibraryModal.razor.cs Outdated
@jschick04 jschick04 force-pushed the jschick/library-modal-followups branch from 84af813 to 7bf44b2 Compare June 7, 2026 01:22
@jschick04 jschick04 requested a review from Copilot June 7, 2026 01:25
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 20 out of 20 changed files in this pull request and generated no new comments.

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