Skip to content

Add a user-facing Cancel control for the scenario Open-from-folder scan - #666

Merged
jschick04 merged 1 commit into
mainfrom
jschick/folder-scan-cancel
Jul 24, 2026
Merged

Add a user-facing Cancel control for the scenario Open-from-folder scan#666
jschick04 merged 1 commit into
mainfrom
jschick/folder-scan-cancel

Conversation

@jschick04

Copy link
Copy Markdown
Collaborator

Closes #656.

Problem

The scenario "Open from folder" scan (folder enumeration plus a parallel per-file channel probe) was only cancellable by disposing the dashboard. There was no busy/progress indicator or Cancel control, and for large or network folders the scan can take a noticeable amount of time.

Approach (persistent masthead Cancel chip)

A status chip in the dashboard masthead surfaces the scan and a Cancel control, driven by a dashboard field so it stays reachable regardless of which scenario or category tab is selected. It has three states:

  • Scanning <scenario> folder for logs... + Cancel
  • Cancelling folder scan for <scenario>... (after Cancel, while the in-flight probe drains)
  • Opening logs for <scenario>... (past the commit boundary; no Cancel, because the open is not cancellable)

Browsing the scenario list and switching category tabs stay enabled; only the launch actions are busy-disabled, so there is no double-launch risk.

Changes

Service (ScenarioLaunchService)

  • LaunchFromFolderAsync gains an optional Func<ScenarioFolderPhase, Task>? onPhase (defaulted null, so existing callers are unaffected).
  • Reports Scanning once the picker returns a folder (cancellation is only meaningful from that point) and Opening once a nonempty match commits to opening logs, gated so Opening is never reported for an outcome that opens nothing.
  • A cancellation recheck after the callback (independent of whether a callback is supplied) so a cancel that lands during the commit still wins before any filter dispatch or log open.

Dashboard (EmptyStateDashboard)

  • Per-launch CancellationTokenSource linked to the component lifetime.
  • Three-state chip plus focus management that keeps Cancel reachable and never strands keyboard focus on the document body (focuses Cancel on scan start; restores to the active category tab or the dashboard root otherwise).
  • Guarded rendering so the busy state is reflected on the banner-retry path, which runs outside the dashboard event loop.
  • The reactive-launch banner "Open from folder" retry is routed through the guarded wrapper so it no longer bypasses the busy guard.

Testing

  • Runtime.Tests: 5 new phase-emission tests (Scanning/Opening boundaries, mid-scan cancel, no-match, cancel-during-Opening). Full suite: 2030/2030.
  • UI.Tests (bUnit): 5 new tests covering chip visibility, decoupling from selection (reselecting a scenario keeps the chip), cancellation acknowledgement with no result dialog, the Opening relabel, and a banner-retry busy-state regression guard. Full suite: 1186/1186.
  • Full-solution build: 0 warnings / 0 errors.

…an (#656)

The scenario "Open from folder" scan (folder enumeration plus a parallel
per-file channel probe) was only cancellable by disposing the dashboard. This
adds a persistent masthead status chip that surfaces the scan and a Cancel
control that stays reachable regardless of which scenario or category tab is
selected.

Service (ScenarioLaunchService): LaunchFromFolderAsync gains an optional
Func<ScenarioFolderPhase, Task>? onPhase callback (defaulted null, so existing
callers are unaffected). It reports Scanning once the picker returns a folder
(cancellation is only meaningful from that point) and Opening once a nonempty
match commits to opening logs, with a cancellation recheck after the callback
so a cancel that lands during the commit still wins before any filter dispatch
or log open.

Dashboard (EmptyStateDashboard): a per-launch CancellationTokenSource linked to
the component lifetime, a three-state masthead chip (Scanning with Cancel,
Cancelling..., Opening logs...), focus management that keeps the Cancel button
reachable and never strands keyboard focus on the document body, and guarded
rendering so the busy state is reflected on the banner-retry path (which runs
outside the dashboard event loop). The reactive-launch banner "Open from
folder" retry is routed through the guarded wrapper so it no longer bypasses
the busy guard.

Tests: service-level phase-emission tests (Scanning/Opening boundaries and
cancellation) plus bUnit tests covering chip visibility, decoupling from
selection, cancellation acknowledgement, the Opening relabel, and the
banner-retry busy-state regression.
Copilot AI review requested due to automatic review settings July 24, 2026 01:27

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds a user-visible, masthead-level progress/cancel affordance for the “Open from folder” scenario scan, enabling in-place cancellation without disposing the dashboard. This is implemented by plumbing scan phase notifications from the runtime launch service into the dashboard so UI state (chip text, Cancel availability, focus restoration, and busy-guards) remains consistent even when the scan is initiated from non-standard paths (e.g., banner retry).

Changes:

  • Extend ScenarioLaunchService.LaunchFromFolderAsync with an optional onPhase callback and introduce ScenarioFolderPhase to report Scanning/Opening boundaries (with cancellation re-check before committing).
  • Add a persistent masthead “Scanning/Cancelling/Opening” chip with a Cancel control, per-launch linked CancellationTokenSource, and explicit focus management in EmptyStateDashboard.
  • Add/adjust unit tests (runtime + bUnit UI) to cover phase emission boundaries, cancellation behavior, chip visibility/labeling, and banner-retry busy-guarding.

Reviewed changes

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

Show a summary per file
File Description
tests/Unit/EventLogExpert.UI.Tests/Dashboard/EmptyStateDashboardTests.cs Adds bUnit coverage for the masthead scan chip states, Cancel behavior, focus/busy guarding, and banner-retry path.
tests/Unit/EventLogExpert.Runtime.Tests/Scenarios/ScenarioLaunchServiceTests.cs Adds runtime coverage for phase reporting boundaries and cancellation timing (incl. cancel during Opening).
src/EventLogExpert.UI/Dashboard/EmptyStateDashboard.razor.css Styles the new scan chip accent to distinguish it from the existing filter-applied chip.
src/EventLogExpert.UI/Dashboard/EmptyStateDashboard.razor.cs Implements per-launch cancellation, guarded rendering for non-event-loop triggers, and focus restoration logic.
src/EventLogExpert.UI/Dashboard/EmptyStateDashboard.razor Renders the masthead chip and Cancel button during the scanning window; makes the dashboard root focusable for safe focus fallback.
src/EventLogExpert.Runtime/Scenarios/ScenarioLaunchService.cs Adds onPhase callback support, emits Scanning after picker success, emits Opening only when committing to open, and rechecks cancellation after callback.
src/EventLogExpert.Runtime/Scenarios/ScenarioFolderPhase.cs Introduces the phase enum used by callers to drive user-visible scan state.
src/EventLogExpert.Runtime/Scenarios/IScenarioLaunchService.cs Updates the service contract and documentation to include the optional onPhase callback.

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

@jschick04
jschick04 marked this pull request as ready for review July 24, 2026 01:37
@jschick04
jschick04 requested a review from a team as a code owner July 24, 2026 01:37

@ryanriesMSFT ryanriesMSFT left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🍆

@jschick04
jschick04 merged commit aba2207 into main Jul 24, 2026
8 checks passed
@jschick04
jschick04 deleted the jschick/folder-scan-cancel branch July 24, 2026 01:53
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.

Add a user-facing Cancel control for the scenario Open-from-folder scan

3 participants