FN-7562: fix mobile oversight menu auto-focus opening a second native select popup
Fixes the mobile oversight overflow menu rendering two overlapping menus by narrowing auto-focus to actionable button menuitems. - Change the menu-open auto-focus effect to query `button.detail-oversight-menu-item` instead of matching any `.detail-oversight-menu-item` element, since the native level `<select>` also carried that class and was matched first. - Programmatically focusing the native `<select>` triggered its OS option picker, which rendered as a second overlapping menu on top of the custom `role="menu"` popover. - Add regression tests covering: auto-focus landing on the first button menuitem when nudge/stop/explain are available, no fallback focus on the select when oversight is off (level-only state), and confirming the desktop inline select is unaffected. - Update dashboard-guide.md docs to describe the fixed auto-focus behavior. Files changed: docs/dashboard-guide.md | 2 +- packages/dashboard/app/components/TaskDetailModal.tsx | 3 +- .../app/components/__tests__/TaskDetailModal.oversight-mobile.test.tsx | 96 ++++++++++++++++++++++ 3 files changed, 99 insertions(+), 2 deletions(-) Fusion-Task-Id: FN-7562 Fusion-Task-Lineage: f39068f1-811f-4663-ade1-ff020a389ae5 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
This commit is contained in:
@@ -201,7 +201,7 @@ Features:
|
||||
<!-- FNXC:PlannerOversight 2026-07-04-20:30: FN-7546 clarifies the cluster above — operators reported the buttons were unlabeled and looked inert, with only a hover title explaining why. Adds a visible group label and an always-visible disabled-reason line, and makes Explain always openable since it never mutates anything. -->
|
||||
- The FN-7517 controls above carry a visible, non-interactive **`"Overseer controls"` group label** (`data-testid="detail-oversight-controls-label"`) so Nudge/Stop/Explain read as an identifiable cluster rather than unlabeled chips; the label is gated by the same `(hasTaskOversightOverride || workflowOversightResolved) && !oversightIsOff` condition as the buttons, so it never renders an empty shell when oversight is Off/unresolved. When **Nudge** is disabled, an always-visible helper line (`data-testid="detail-overseer-nudge-disabled-reason"`) states the reason in-DOM (mirroring the existing hover `title`) instead of relying on a mouse-hover tooltip alone. **Explain** is read-only and non-mutating, so it is never disabled purely because the overseer is inactive — clicking it always opens/closes the panel, which shows the overseer's live state when watching or an informative "not currently watching this task" message otherwise. Nudge's mutating enablement rule (`canNudgeOverseer`, including the human-control suppression cases) and Stop's confirmation dialog are unchanged.
|
||||
<!-- FNXC:PlannerOversight 2026-07-04-19:00: FN-7545 collapses the above controls into a mobile overflow menu below the 768px breakpoint. -->
|
||||
- On mobile (viewport ≤ 768px), the level-select/nudge/stop/explain controls above collapse behind a single compact **"Oversight" overflow-menu button** (`data-testid="detail-oversight-menu-trigger"`, `MoreVertical` icon, `aria-haspopup="menu"`) that opens a `role="menu"` popover (mirroring the existing move-action dropdown pattern) listing the same controls as full-width, comfortably tappable `role="menuitem"` entries with the SAME testids and enablement/visibility rules as the desktop inline controls. The trigger itself is withheld entirely when none of those controls would render (no empty-shell overflow button for the oversight-off + overseer-inactive default). Desktop (>768px) keeps the inline cluster unchanged.
|
||||
- On mobile (viewport ≤ 768px), the level-select/nudge/stop/explain controls above collapse behind a single compact **"Oversight" overflow-menu button** (`data-testid="detail-oversight-menu-trigger"`, `MoreVertical` icon, `aria-haspopup="menu"`) that opens a `role="menu"` popover (mirroring the existing move-action dropdown pattern) listing the same controls as full-width, comfortably tappable `role="menuitem"` entries with the SAME testids and enablement/visibility rules as the desktop inline controls. The trigger itself is withheld entirely when none of those controls would render (no empty-shell overflow button for the oversight-off + overseer-inactive default). Desktop (>768px) keeps the inline cluster unchanged. Opening the menu presents exactly one surface: menu-open auto-focus lands on the first actionable button menuitem, never the native level `<select>`, so the OS option picker never auto-opens on top of the custom popover (FN-7562).
|
||||
<!-- FNXC:PlannerOversight 2026-07-04-18:00: FN-7519 adds a read-only Intervention Timeline immediately below the FN-7517 controls above. -->
|
||||
- Below the quick oversight controls, the task detail modal renders an **Intervention Timeline** (`data-testid="planner-intervention-timeline"`) listing every recorded planner-overseer intervention for the task, newest-first: watched stage, reason, action taken, outcome (with a `.status-dot` indicator using semantic outcome tokens), an attempt count/limit badge (only when both are present), and source links (agent log / review comment / failed check / merge error / PR state / generic URL). It renders a calm "No planner interventions yet" empty state rather than an empty shell when there are none, and is hidden entirely (no leftover container) when oversight is off or unresolved for the task. Entries are read via `GET /tasks/:id/overseer/interventions`, which assembles them from the existing run-audit store under the `overseer:intervention` mutation type (`recordPlannerIntervention`/`getPlannerInterventionTimeline` in `@fusion/core`). This is a pure read surface — FN-7520 wires the actual intervention-producing call-sites.
|
||||
- Task detail surfaces show the selected/effective workflow identity near the task's workflow controls so individual cards remain understandable when Board is in **All workflows** or another aggregate/mixed context.
|
||||
|
||||
Reference in New Issue
Block a user