From bb3bd3da4d72a97d5ed7493fb5e4f3cba38e8718 Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 25 May 2026 14:54:15 +0100 Subject: [PATCH] Frontend component cleanup (#2495) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(frontend): add Modal primitive on Radix Dialog (P1.1) Adds frontend/src/components/ui/modal.tsx — a thin wrapper around the existing Dialog/DialogContent primitives that preserves the legacy WrapperModal visual contract (bg-card, rounded-2xl, p-8, blurred backdrop) while inheriting Radix's focus-trap, body-scroll lock, and Esc handling. Always renders a DialogTitle (wrapped in VisuallyHidden when hideTitle is set) so modals stop logging a11y warnings on adoption. No consumers migrated yet. * refactor(frontend): migrate ConfirmationModal to Modal primitive (P1.2) Swaps WrapperModal for the new Radix-backed Modal so consumers inherit focus trap, body scroll lock, and Esc-to-close. Footer DOM order flipped from [Submit, Cancel] (flex-row-reverse) to [Cancel, Submit] so tab order now matches visual order; visual layout unchanged. Message renders as DialogTitle for proper screen-reader announcement. * refactor(frontend): inline DeleteConvModal into Navigation (P1.3) DeleteConvModal was a thin Redux wrapper around ConfirmationModal with a single consumer and a dead useOutsideAlerter on an unbound ref. Inlined the direct ConfirmationModal call at the call site and deleted the wrapper file. * refactor(frontend): migrate 5 small modals to Modal primitive (P1.4) Migrates FolderManagementModal, AddActionModal, JWTModal, ShareConversationModal and SearchConversationsModal off WrapperModal onto the Radix-backed Modal so they gain focus trap, scroll lock, and consistent DialogTitle a11y. Footer DOM order normalised so tab order matches visual order. JWTModal stays intentionally uncloseable via isPerformingTask; P1.7 revisits. Also wraps DialogDescription in VisuallyHidden when no description is provided, silencing the Radix "Missing Description" console warning that consumers without a subtitle were triggering. * refactor(frontend): migrate 5 medium modals to Modal primitive (P1.5a) Migrates AddToolModal, AgentDetailsModal, ConfigToolModal, ImportSpecModal and MoveToFolderModal off WrapperModal. They now inherit focus trap, scroll lock, Esc-to-close and consistent DialogTitle a11y. Footers reordered to natural DOM order so tab order matches visual order. AddToolModal's dead useOutsideAlerter on an unbound ref removed. * refactor(frontend): migrate 5 large modals to Modal primitive (P1.5b) Migrates PromptsModal, CustomModelModal, MCPServerModal, ScheduleFormModal and Upload off WrapperModal. These were the last remaining consumers of the legacy modal wrapper outside of the shared WrapperModalPropsType (kept temporarily for P1.9 cleanup). CustomModelModal continues to set isPerformingTask while saving; P1.7 revisits Esc behavior during locked submits. * refactor(frontend): migrate AgentTypeModal to Modal primitive (P1.6) AgentTypeModal was the last hand-rolled fixed-inset overlay in the codebase. Swapping to Modal gives it focus trap, Esc-to-close, body scroll lock and consistent DialogTitle a11y — none of which the legacy overlay implemented. * fix(frontend): let users dismiss CustomModel and Schedule modals during save (P1.7) Drops isPerformingTask on CustomModelModal and ScheduleFormModal so Esc / click-outside / the X button all close the modal while a save is in flight. The Save button itself stays disabled so users can't double-submit. SchedulesView.closeModal was also gating on submitting; that lock is removed too. The in-flight network call continues in the background. JWTModal remains intentionally uncloseable — it gates app access on auth, not a transient save state. * style(frontend): normalise modal CTA radius to rounded-3xl (P1.8) ConfigToolModal, JWTModal, ShareConversationModal and ScheduleFormModal previously used rounded-full for their primary CTAs while the rest of the modal suite uses rounded-3xl. Switches the four outliers and pads font-medium where missing. Footer DOM order across all migrated modals was already corrected to natural order during P1.2 / P1.4 / P1.5, so no further reorderings here. * chore(frontend): delete legacy WrapperModal (P1.9) All 14 consumers were migrated to the Radix-backed Modal primitive across P1.2-P1.6. Drops the legacy WrapperModal.tsx, the orphan WrapperModalPropsType type re-export, and updates the stale z-index comment in TimezoneCombobox to reference Modal's z-50. * feat(frontend): add floating-label variant to ui/input (P2.1) Extends the shadcn Input primitive with an optional label prop and leftIcon/required/labelBgClassName slots so consumers can swap the legacy components/Input.tsx without losing the peer-based floating label UX. Existing bare-input usage is unchanged. * refactor(frontend): migrate 9 callers off components/Input.tsx (P2.2) Switches ToolConfig, PromptsModal, AddActionModal, JWTModal, ToolsPopup, SourcesPopup, MultiSelectPopup, FilePicker and Upload to the ui/input floating-label variant. Drops legacy knobs that the audit flagged as cruft (colorVariant, borderVariant, textSize, edgeRoundness); inputs converge on rounded-md and 1px borders. The biggest visible delta is PromptsModal's prompt-name field — pill -> rounded-md rectangle, intentional. * chore(frontend): delete legacy components/Input.tsx (P2.3) All 9 consumers were migrated in P2.2. Removes the legacy component and the unused InputProps type from components/types. * refactor(frontend): migrate 7 raw text inputs to ui/input (P2.4) Swaps the page-level search inputs on Sources, Tools, CustomModels and AgentsList, plus the inline new-folder input on AgentsList, the FolderManagementModal field, and SearchConversationsModal, onto the ui/input primitive. Page searches now use the floating label / leftIcon slot. Complex per-method or workflow-editor inputs deferred. Also clears the trailing-newline lint error in modals/types after the WrapperModalPropsType deletion. * feat(frontend): add destructive-outline button variant (P2.5) Adds the red-outlined danger button pattern (border-destructive text-destructive on transparent ground, filling to bg-destructive on hover) so callers like "Delete All" CTAs can adopt the primitive instead of hand-rolling the class string. * refactor(frontend): migrate settings/ buttons to ui/button (P2.6) Replaces 10 raw