Files
fusion/docs/dashboard-modal-inventory.md
gsxdsm e4cb957b57 FN-8619: migrate modal geometry to FloatingWindow
Unify migrated modal geometry and responsive behavior under FloatingWindow.

- Cover Agent Detail and GitHub Import floating-window interaction and persistence contracts.
- Preserve unique Agent Detail labels, mouse-only backdrop dismissal, and tablet touch layouts.
- Update the dashboard modal migration inventory.

Files changed:
 docs/dashboard-modal-inventory.md                  |   6 +-
 .../dashboard/app/components/AgentDetailView.css   |  49 +++++-----
 .../dashboard/app/components/AgentDetailView.tsx   |   6 +-
 .../dashboard/app/components/FloatingWindow.css    |  10 +-
 .../dashboard/app/components/TaskDetailModal.css   |  15 +++
 .../AgentDetailView.floating-window.test.tsx       | 102 +++++++++++++++++++++
 .../__tests__/GitHubImportModal.test.tsx           |  58 ++++++++++++
 ...etailModal.responsive-and-dependencies.test.tsx |  24 +++++
 8 files changed, 241 insertions(+), 29 deletions(-)

Fusion-Task-Id: FN-8619

Fusion-Task-Lineage: efa95e41-b12e-4e5d-aeb2-65b43c2dd8e0

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-26 20:04:33 -07:00

14 KiB
Raw Blame History

Dashboard modal inventory

Canonical copy: This committed file is the durable canonical inventory. The identical modal-inventory task document lives on FN-8617 because task documents are per-task and cannot be added retroactively to FN-8605 or archived FN-8615.

Evidence scope and row accounting

Evidence was re-derived from main at 743dc5f46ea5ebf53ff81ce1a9722ce9ef29d37a. The revision-qualified glob command (git ls-tree --name-only -r main -- packages/dashboard/app/components | grep -E 'Modal\\.tsx$') returned 40 files. Of the named extras, 2 were not in that glob (AgentDetailView.tsx, WorkflowNodeEditor.tsx); RightDockExpandModal.tsx matches the glob and appears exactly once.

The required ArtifactsGallery.tsx grep found three distinct viewer pop-outs—MediaLightbox, PdfViewer, and DocViewer—which each render through OverlayShell; therefore it contributes 3 rows (not one vague aggregate row). The deduplicated union source-file set contains 43 files and the union row count is 45 (40 + 2 + 3).

The revision-qualified FloatingWindow, useModalResizePersist, shared-contract, and structural searches were recorded in the table below. The bespoke pointer/drag/resize search was run across all 43 union source-file pathspecs, explicitly including AgentDetailView.tsx, WorkflowNodeEditor.tsx, and ArtifactsGallery.tsx; its positive surface-geometry candidates were New Task, Right Dock Expand, and Terminal. Matches in other files were inspected and are internal content controls (for example a sidebar splitter, list reordering, or a nested Files-pane splitter), not modal move/resize mechanisms.

For every D row, the cited structural construct was directly inspected at this revision along with its imports, handlers, geometry state, and corresponding local styling references. The note “direct inspection” means no surface-level touch/pointer capture, custom useDrag/useResize, drag/resize library, pointer-written window geometry, or CSS resize mechanism exists; where a pointer-token match existed, the note records why it does not move or resize the modal itself.

Shared migration contract

Migrations use FloatingWindow with a stable geometry-persistence key and consume isTabletTouchViewport from useViewportMode.ts, never bare @media (pointer: coarse). Effective move/resize hit targets are at least 44px and marked data-resize-hit-target="true". Phone-class is ≤767.98px and tablet-class starts at 768px; JavaScript and CSS boundaries must stay in sync. A headerless window using hideHeader plus dragHandleSelector must put the same hit-target contract on its resolved delegated handle. closeOnOutsidePointerDown defaults off, so a modal intended to dismiss on outside pointer-down must opt in explicitly.

Classifications

Surface Class Evidence (all at main SHA above) Target Owning subtask Risk notes Opt-out justification
ActivityLogModal.tsx A ActivityLogModal.tsx:486 <FloatingWindow already migrated FN-8606 core/workflow (done) Embedded dock variant; header delegation. —
AddNodeModal.tsx A AddNodeModal.tsx:260 <FloatingWindow already migrated FN-8606 core/workflow (done) Headerless delegated handle. —
AgentDetailView.tsx B AgentDetailView.tsx <FloatingWindow> already migrated FN-8619 Modal uses floating-window:agent-detail; paired mouse-only backdrop dismissal remains. Legacy size-only key is orphaned (one-time reset). Inline presentation is explicitly gated by inline because its owner retains the detail layout and lifecycle.
AgentErrorDetailsModal.tsx D AgentErrorDetailsModal.tsx:65 .modal-overlay, role="dialog"; direct inspection: no geometry mechanism. stays static FN-8607 agent/onboarding/utility Short blocking error-detail acknowledgement. Error detail is a brief, fault-recovery acknowledgement; moving/resizing would add state to an urgent recovery path.
AgentGenerationModal.tsx D AgentGenerationModal.tsx:169 role="dialog"; direct inspection: no geometry mechanism. migrate → FloatingWindow FN-8607 agent/onboarding/utility Generation progress can be long-running. —
AgentImportModal.tsx D AgentImportModal.tsx:473 role="dialog" aria-modal; direct inspection: no geometry mechanism. migrate → FloatingWindow FN-8607 agent/onboarding/utility Import mapping has nested scroll. —
AgentListModal.tsx D AgentListModal.tsx:289 .modal-overlay / dialog; direct inspection: no geometry mechanism. migrate → FloatingWindow FN-8607 agent/onboarding/utility List selection and outside dismissal. —
AgentOnboardingModal.tsx D AgentOnboardingModal.tsx:194 .modal-overlay; direct inspection: no geometry mechanism. migrate → FloatingWindow FN-8607 agent/onboarding/utility Onboarding step chrome. —
ArtifactsGallery.tsx#MediaLightbox A ArtifactsGallery.tsx:532 MediaLightbox; shared OverlayShell at :477 <FloatingWindow already migrated n/a Focused media viewer; headerless delegated handle. —
ArtifactsGallery.tsx#PdfViewer A ArtifactsGallery.tsx:568 PdfViewer; shared OverlayShell at :477 <FloatingWindow already migrated n/a PDF viewer with nested browser scroll. —
ArtifactsGallery.tsx#DocViewer A ArtifactsGallery.tsx:706 OverlayShell; :593 DocViewerProps already migrated n/a Sandboxed HTML/markdown preview; headerless delegated handle. —
ChangesDiffModal.tsx A ChangesDiffModal.tsx:123 <FloatingWindow already migrated FN-8606 core/workflow (done) Diff scroll and delegated header. —
ConnectNodeModal.tsx A ConnectNodeModal.tsx:171 <FloatingWindow already migrated FN-8606 core/workflow (done) Headerless delegated handle. —
CreateRoomModal.tsx D CreateRoomModal.tsx <FloatingWindow windowKey="create-room"> already migrated FN-8621 floating-window:create-room; explicit outside-pointer dismissal; member-picker remains nested scroll owner. —
DockerNodeOnboardingModal.tsx D DockerNodeOnboardingModal.tsx:214 .modal-overlay; direct inspection: no geometry mechanism. migrate → FloatingWindow FN-8607 agent/onboarding/utility Onboarding commands and scroll. —
DuplicateWarningModal.tsx D DuplicateWarningModal.tsx:41 .modal-overlay; direct inspection: no geometry mechanism. stays static n/a Small duplicate-decision confirmation. This intentionally compact confirmation should stay centered and transient rather than acquire persisted window state.
ExperimentalAgentOnboardingModal.tsx D ExperimentalAgentOnboardingModal.tsx:187 .modal-overlay; direct inspection: no geometry mechanism. migrate → FloatingWindow FN-8607 agent/onboarding/utility Experimental onboarding step chrome. —
FileBrowserModal.tsx A FileBrowserModal.tsx:372 <FloatingWindow already migrated n/a Nested Files-pane splitter is content layout, not window geometry. —
GitHubImportModal.tsx B GitHubImportModal.tsx root <FloatingWindow>; nested import detail remains floating already migrated FN-8619 Modal uses floating-window:github-import; nested import detail remains floating; legacy size-only key is replaced (one-time reset). useEmbeddedPresentation / resizePersistEnabled explicitly keeps embedded import container-filling.
GitManagerModal.tsx A GitManagerModal.tsx:1385 <FloatingWindow already migrated FN-8606 core/workflow (done) Embedded right-dock presentation. —
GroupTaskModal.tsx A GroupTaskModal.tsx:107 <FloatingWindow already migrated FN-8606 core/workflow (done) Branch-group detail and header delegation. —
MailboxModal.tsx D MailboxModal.tsx:731 .modal-overlay; direct inspection: no geometry mechanism. migrate → FloatingWindow FN-8607 agent/onboarding/utility Thread/detail nested scroll. —
MilestoneSliceInterviewModal.tsx D MilestoneSliceInterviewModal.tsx:410 .modal-overlay; direct inspection: no geometry mechanism. migrate → FloatingWindow FN-8607 agent/onboarding/utility Interview flow with step chrome. —
MissionInterviewModal.tsx A MissionInterviewModal.tsx:812 <FloatingWindow already migrated n/a Plan Mission workspace; headerless delegated handle. —
ModelOnboardingModal.tsx A ModelOnboardingModal.tsx:2438 <FloatingWindow already migrated FN-8606 core/workflow (done) Long provider onboarding flow. —
ModelSelectionModal.tsx D ModelSelectionModal.tsx:195 .modal-overlay role="dialog"; direct inspection: no geometry mechanism. stays static FN-8607 agent/onboarding/utility Compact blocking model choice. Model selection is a deliberately short, focused choice dialog; persistent movable geometry is unnecessary and risks obscuring the required selection.
NativeShellOnboardingModal.tsx D NativeShellOnboardingModal.tsx:48 .modal-overlay; direct inspection: no geometry mechanism. migrate → FloatingWindow FN-8607 agent/onboarding/utility Native-shell onboarding instructions. —
NewTaskModal.tsx A FloatingWindow (new-task), headerless delegated drag host. already migrated FN-8620 Phone sheet and focus trap remain; fusion:new-task-modal-size / -position superseded by fusion:new-task-modal-geometry (one-time reset). —
NodeDetailModal.tsx A NodeDetailModal.tsx:442 <FloatingWindow already migrated FN-8606 core/workflow (done) Headerless delegated handle. —
PlanningModeModal.tsx A PlanningModeModal.tsx:3548 <FloatingWindow already migrated FN-8606 core/workflow (done) Planner has internal sidebar and list drag controls; shell geometry is shared. —
PrCreateModal.tsx A PrCreateModal.tsx:549 <FloatingWindow already migrated n/a Create-PR form; delegated header. —
ReportModal.tsx D ReportModal.tsx:79 role="dialog" aria-modal; direct inspection: no geometry mechanism. stays static n/a Short reporting-action dialog. Reporting is a brief confirmation/input flow; a fixed centered dialog preserves its blocking, one-shot interaction.
ResearchTaskActionModal.tsx D ResearchTaskActionModal.tsx:57 .modal-overlay; direct inspection: no geometry mechanism. stays static n/a Small action confirmation. The modal is a bounded task-action confirmation, so persistent drag/resize state would be needless interaction cost.
RightDockExpandModal.tsx A FloatingWindow (right-dock-expand), headerless delegated drag host. already migrated FN-8620 Dock-origin content remains; legacy size/position pair superseded by fusion:right-dock-expand-modal-geometry (one-time reset). The expanded shell floats while content retains explicit dock-origin surface: "expand" behavior.
ScheduledTasksModal.tsx A ScheduledTasksModal.tsx:560 <FloatingWindow already migrated FN-8606 core/workflow (done) Embedded automation presentation. —
ScriptsModal.tsx A ScriptsModal.tsx:181 <FloatingWindow already migrated FN-8606 core/workflow (done) Script output nested scroll. —
SettingsModal.tsx A SettingsModal.tsx:4632 <FloatingWindow already migrated FN-8606 core/workflow (done) Embedded destination and internal nav-width splitter. —
SettingsSyncConflictModal.tsx D SettingsSyncConflictModal.tsx:218 .modal-overlay; direct inspection: no geometry mechanism. stays static n/a Blocking conflict resolution. Sync conflict resolution must remain an immediately legible centered blocking decision, not a persisted workspace window.
SetupWizardModal.tsx D SetupWizardModal.tsx:452 .modal-overlay role="dialog"; direct inspection: no geometry mechanism. migrate → FloatingWindow FN-8607 agent/onboarding/utility First-run step chrome and blocking setup. —
StashConflictModal.tsx D StashConflictModal.tsx:236 .modal-overlay role="dialog"; direct inspection: no geometry mechanism. stays static n/a Blocking git-conflict recovery. The conflict resolver is an urgent bounded recovery decision; centered static presentation keeps the destructive choices visible.
SubtaskBreakdownModal.tsx D SubtaskBreakdownModal.tsx:607 .modal-overlay role="dialog"; direct inspection: list draggable controls reorder subtasks only, not window geometry. migrate → FloatingWindow FN-8607 agent/onboarding/utility Nested subtask drag/reorder; panel itself is static. —
TaskDetailModal.tsx B TaskDetailModal.tsx <FloatingWindow layer="task-detail"> already migrated FN-8619 Dense tabs and pop-out stacking retained; task-detail-modal-size is orphaned for floating-window:task-detail (one-time reset). —
TerminalModal.tsx A Floating mode uses FloatingWindow (terminal-<project>), headerless delegated drag host. already migrated FN-8620 Floating legacy pair superseded by fusion:terminal-float-geometry-<project> (one-time reset). Docked mode is explicitly gated and retains its top-edge resize / fusion:terminal-docked-height-<project> because it owns dock layout.
WorkflowAddStepModal.tsx A WorkflowAddStepModal.tsx:144 <FloatingWindow already migrated FN-8606 core/workflow (done) Headerless delegated handle. —
WorkflowNodeEditor.tsx A WorkflowNodeEditor.tsx:5646 <FloatingWindow; :19 createPortal already migrated n/a Full-screen workflow editor, delegated header. —

Completeness check

The table contains 45 rows: 40 glob rows, 2 non-glob named-extra rows, and 3 independently classified ArtifactsGallery.tsx viewer rows. RightDockExpandModal.tsx occurs once. All class-D rows provide a concrete structural file:line citation plus direct-inspection result; every stays static row has an explicit rationale. FN-8606’s landed core/workflow surfaces are class A and marked already migrated; the remaining FN-8607 assignments match its agent/onboarding/ utility batch, with intentionally static confirmations assigned n/a where no migration is due.