refactor(frontend): organize components into feature folders and split oversized files#73
Merged
Merged
Conversation
Move the ~57 flat files in frontend/components into feature-based subfolders (shared, layout, investigations, watches, playbooks, repos, codefix, connections, mcp, docs) plus the existing sessions/wiki/inputs, and standardize every component-to-component import on the @/components/<folder>/<Name> alias. Pure reorganization; no behavior change. Files moved with git mv to preserve history.
…iblings Break the ten largest component files into dot-namespaced sibling files in the same folder (reducers, helpers, types, and trailing leaf sub-components lifted out), leaving each main component body intact. Pure structural change; no behavior change. PlaybookEditor 1932 -> 1538 SessionView 1734 -> 1160 Sidebar 1284 -> 583 PlaybookList 998 -> 682 NodeEditor 754 -> 163 WikiProposalCard 730 -> 516 PlaybookGraph 622 -> 169 RepoArchitectureView 604 -> 357 LinkedReposPanel 601 -> 117 DocsView 517 -> 185
Contributor
There was a problem hiding this comment.
Pull request overview
This PR refactors the frontend component structure by organizing components into feature-based folders and standardizing imports to @/components/<folder>/<Name>, while also splitting previously oversized components into smaller co-located modules to improve navigability and maintainability.
Changes:
- Reorganized
frontend/componentsinto feature folders (e.g.shared/,layout/,playbooks/,watches/,repos/,docs/, etc.) and updated imports to use the standardized alias form. - Extracted shared UI primitives/utilities (e.g.
Spinner,Markdown,Icons,ToolCard, pickers/builders) intocomponents/shared/and updated callsites. - Split/introduced feature modules for larger surfaces (e.g. playbook graph/editor parts, docs view, watch panels, investigation view parts) to reduce file size and co-locate related logic.
Reviewed changes
Copilot reviewed 111 out of 132 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| frontend/components/wiki/WikiUpstreamHeader.tsx | Update icon imports to shared Icons location. |
| frontend/components/wiki/WikiProposalNotifier.tsx | Add notifier bridging stream events to DOM event for sidebar refresh. |
| frontend/components/wiki/WikiProposalNotifier.test.tsx | Update test import to aliased path. |
| frontend/components/wiki/WikiProposalCard.tsx | Extract preview/files helpers and standardize imports. |
| frontend/components/wiki/WikiProposalCard.test.tsx | Update test import to aliased path. |
| frontend/components/wiki/WikiProposalCard.preview.tsx | New extracted preview/frontmatter parsing helpers. |
| frontend/components/wiki/WikiProposalCard.files.tsx | New extracted raw file rendering helpers. |
| frontend/components/wiki/WikiNodeEditor.tsx | Update icon imports to shared Icons location. |
| frontend/components/wiki/WikiHome.tsx | Use shared Spinner/Paginator imports. |
| frontend/components/wiki/WikiGraphNodes.tsx | Update icon imports to shared Icons location. |
| frontend/components/wiki/WikiEditor.tsx | Update imports (shared UI + moved playbook/wiki components). |
| frontend/components/wiki/WikiBodyTab.tsx | Use shared Markdown/Icons imports. |
| frontend/components/wiki/PushWikiPRModal.tsx | Use shared Spinner/CopyButton imports. |
| frontend/components/wiki/NewWikiEntryModal.tsx | Use shared Spinner/SlackChannelPicker imports. |
| frontend/components/wiki/EntryRow.tsx | Update icon import to shared Icons location. |
| frontend/components/watches/WatchStatusPill.tsx | New watch status pill component with labels/tooltips. |
| frontend/components/watches/WatchSignalsPanel.tsx | Standardize SignalCard import to aliased path. |
| frontend/components/watches/WatchQueueStrip.tsx | New queue strip component (fetch + SSE refresh). |
| frontend/components/watches/WatchItemsPanel.tsx | New items panel component with filtered toggle + items list. |
| frontend/components/watches/WatchIngestRunsPanel.tsx | Use shared Spinner import. |
| frontend/components/watches/WatchForm.tsx | Use shared FilterBuilder/SlackChannelPicker imports. |
| frontend/components/watches/WatchForm.test.tsx | Update test import to aliased path. |
| frontend/components/watches/WatchesList.tsx | Use shared Icons/Spinner and aliased WatchStatusPill import. |
| frontend/components/watches/WatchesList.test.tsx | Update test import to aliased path. |
| frontend/components/watches/WatchDetailHeader.tsx | Use shared Icons/Spinner and aliased WatchStatusPill import. |
| frontend/components/watches/StartFromSignalDialog.tsx | New dialog component for starting investigations from a signal. |
| frontend/components/watches/SignalCard.tsx | Use shared Icons and aliased StartFromSignalDialog import. |
| frontend/components/watches/SignalCard.test.tsx | Update test import to aliased path. |
| frontend/components/watches/AllWatchesSignalsPanel.tsx | New merged signals panel across watches (parallel fetch + SSE refresh). |
| frontend/components/shared/ToolCard.tsx | New shared tool card rendering (inputs/results + nested activity). |
| frontend/components/shared/Spinner.tsx | New shared Spinner component. |
| frontend/components/shared/SlackChannelPicker.tsx | Update to use shared Spinner/FilterableList imports. |
| frontend/components/shared/Paginator.tsx | Update icon import to shared Icons location. |
| frontend/components/shared/Markdown.tsx | New shared Markdown renderer for transcript surfaces. |
| frontend/components/shared/Icons.tsx | Relocated icon surface and updated comment/examples. |
| frontend/components/shared/FilterBuilder.tsx | New shared filter builder for watches. |
| frontend/components/shared/FilterBuilder.test.tsx | Update test import to aliased path. |
| frontend/components/shared/FilterableList.tsx | New shared filterable list component extracted for reuse. |
| frontend/components/shared/EntityChipsInput.tsx | New shared chips input for playbook entity tags. |
| frontend/components/shared/EntityChipsInput.test.tsx | Update test import to aliased path. |
| frontend/components/shared/CopyButton.tsx | Update icon import to shared Icons location. |
| frontend/components/sessions/UpstreamHome.tsx | Use shared Spinner/Paginator imports. |
| frontend/components/sessions/SessionUpstreamHeader.tsx | Update icon imports to shared Icons location. |
| frontend/components/sessions/SessionDoc.tsx | Use shared Markdown/Spinner imports. |
| frontend/components/sessions/SessionCard.tsx | Use shared ExternalLinkIcon import. |
| frontend/components/sessions/PushSessionPRModal.tsx | Use shared Icons/Spinner and updated PushState import path. |
| frontend/components/repos/RepoSummaryStateProvider.tsx | New provider for repo summary status + toast updates via stream. |
| frontend/components/repos/RepoActivityPanel.tsx | Use shared Icons/Spinner imports. |
| frontend/components/repos/LinkedReposPanel.tsx | New linked repos sidebar panel with persisted expand + manage modal. |
| frontend/components/repos/LinkedReposPanel.list.tsx | New repo list rendering + status seeding via summary provider. |
| frontend/components/playbooks/YamlPanel.tsx | Use shared Icons/CopyButton imports. |
| frontend/components/playbooks/ToolPicker.tsx | New searchable tool dropdown for playbook editor. |
| frontend/components/playbooks/SaveDialog.tsx | Use shared Spinner import. |
| frontend/components/playbooks/ProposalCard.tsx | Use shared Spinner and updated ProposalBodyTabs import. |
| frontend/components/playbooks/ProposalBodyTabs.tsx | Update imports for relocated PlaybookGraph/Proposal types. |
| frontend/components/playbooks/PlaybookList.parts.tsx | Extract playbook list footer/pagination parts and use shared Icons. |
| frontend/components/playbooks/PlaybookList.badges.tsx | Extract playbook list badge components. |
| frontend/components/playbooks/PlaybookGraph.tsx | New playbook graph wrapper using xyflow + extracted helpers. |
| frontend/components/playbooks/PlaybookGraph.layout.ts | New extracted graph layout/diff+dagre builder. |
| frontend/components/playbooks/PlaybookGraph.edges.tsx | New extracted custom edge renderer for conditions. |
| frontend/components/playbooks/PlaybookEditor.reducer.ts | New extracted reducer/helpers/types for playbook editor state. |
| frontend/components/playbooks/PlaybookEditor.parts.tsx | New extracted UI parts for playbook editor tabs/actions. |
| frontend/components/playbooks/NodeEditor.tsx | New extracted node editor component. |
| frontend/components/playbooks/NodeEditor.pickers.tsx | New extracted handoff/delegate pickers. |
| frontend/components/playbooks/NodeEditor.lists.tsx | New extracted list editors (branches/args/suggested calls). |
| frontend/components/playbooks/NodeEditor.inputs.tsx | New extracted tool input helpers + args editor. |
| frontend/components/playbooks/NodeEditor.fields.tsx | New extracted field wrappers + shared input classnames. |
| frontend/components/playbooks/NewTypeModal.tsx | Use shared Spinner import. |
| frontend/components/playbooks/EditorChatDrawer.tsx | Use shared Markdown/Spinner/ToolCard and updated imports. |
| frontend/components/playbooks/DeleteTypeModal.tsx | Use shared Spinner import. |
| frontend/components/playbooks/CommitsDropdown.tsx | New commits dropdown with lazy “more” loading. |
| frontend/components/mcp/MCPStatusBar.tsx | New/updated MCP status bar with probe polling + telemetry. |
| frontend/components/mcp/MCPCatalogView.tsx | Use shared Spinner import. |
| frontend/components/layout/TopNav.tsx | New top navigation component with route-derived active tab. |
| frontend/components/layout/Sidebar.utils.tsx | New sidebar helper utilities (sync icon + relative time + view mapping). |
| frontend/components/layout/Sidebar.test.tsx | Update test import to aliased path. |
| frontend/components/layout/Sidebar.invRow.tsx | New extracted investigation row rendering with rename UX. |
| frontend/components/layout/AppShell.tsx | Update imports to new layout folder structure. |
| frontend/components/investigations/SessionWorkspace.tsx | Update imports to aliased feature paths. |
| frontend/components/investigations/SessionView.test.tsx | Update test import to aliased path. |
| frontend/components/investigations/SessionView.status.tsx | New extracted status/badge/action button helpers. |
| frontend/components/investigations/SessionView.icons.tsx | New extracted small SVG icon components used in session UI. |
| frontend/components/investigations/SessionView.header.tsx | New extracted session header (back link, export, latest summary jump). |
| frontend/components/investigations/SessionView.banners.tsx | New extracted auto-mode banners (takeover/finished). |
| frontend/components/investigations/InvestigationForm.tsx | Update shared Spinner/Icons imports. |
| frontend/components/investigations/InvestigationForm.test.tsx | Update test import to aliased path. |
| frontend/components/investigations/ActivityPanel.tsx | Update imports to shared ToolCard/MCPStatusBar + shared Icons. |
| frontend/components/investigations/ActivityPanel.test.tsx | Update test import to aliased path. |
| frontend/components/inputs/SlackChannelInput.tsx | Update SlackChannelPicker import to shared folder. |
| frontend/components/inputs/ClusterIdInput.tsx | Update FilterableList/Spinner imports to shared folder. |
| frontend/components/docs/DocsView.utils.ts | New docs utilities (outline extraction + slugging). |
| frontend/components/docs/DocsView.tsx | New docs surface with section switching + outline tracking. |
| frontend/components/docs/DocsView.nav.tsx | New docs nav section/outline UI. |
| frontend/components/docs/DocsView.markdown.tsx | New docs markdown renderer with Mermaid support + heading anchors. |
| frontend/components/connections/ConnectionsPanel.tsx | Update Icons/Spinner imports to shared folder. |
| frontend/components/connections/ConnectionsPanel.test.tsx | Update test import to aliased path. |
| frontend/components/connections/ClusterPicker.tsx | Update Spinner/FilterableList imports to shared folder. |
| frontend/components/codefix/PushPRModal.tsx | Update Spinner/CopyButton imports to shared folder. |
| frontend/components/codefix/CodefixPRStateProvider.tsx | New provider for codefix PR state updates via stream. |
| frontend/components/codefix/CodefixProposalCard.tsx | Update provider import to aliased path. |
| frontend/components/codefix/CodefixProposalCard.test.tsx | Update test imports to aliased paths. |
| frontend/app/(main)/watches/new/page.tsx | Update WatchForm import to new watches folder. |
| frontend/app/(main)/watches/client.tsx | Update watches component imports to new watches folder. |
| frontend/app/(main)/watches/[id]/edit/client.tsx | Update WatchForm import to new watches folder. |
| frontend/app/(main)/watches/[id]/client.tsx | Update watch detail component imports to new watches folder. |
| frontend/app/(main)/repos/page.tsx | Update RepoArchitectureView import to repos folder. |
| frontend/app/(main)/repos/client.tsx | Update shared UI imports + RepoSummaryStateProvider import path. |
| frontend/app/(main)/playbooks/page.tsx | Update PlaybookList/PlaybookEditor imports to playbooks folder. |
| frontend/app/(main)/mcp/page.tsx | Update MCPCatalogView import to mcp folder. |
| frontend/app/(main)/layout.tsx | Update component imports to new folders + providers/notifier paths. |
| frontend/app/(main)/investigations/page.tsx | Update Spinner import to shared folder. |
| frontend/app/(main)/investigations/new/page.tsx | Update InvestigationForm import to investigations folder. |
| frontend/app/(main)/investigations/client.tsx | Update imports to new folders for workspace + shared UI. |
| frontend/app/(main)/docs/page.tsx | Update DocsView import to docs folder. |
| frontend/app/(main)/docs/[section]/client.tsx | Update DocsView import to docs folder. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+62
to
+67
| <button | ||
| type="button" | ||
| onClick={() => setExpanded((v) => !v)} | ||
| aria-expanded={expanded} | ||
| className="flex w-full items-center justify-between gap-2 px-3 py-2.5 text-left transition hover:bg-zinc-900/40" | ||
| > |
Comment on lines
+74
to
+91
| <span | ||
| role="button" | ||
| tabIndex={0} | ||
| onClick={(e) => { | ||
| e.stopPropagation(); | ||
| setManageOpen(true); | ||
| }} | ||
| onKeyDown={(e) => { | ||
| if (e.key === "Enter" || e.key === " ") { | ||
| e.preventDefault(); | ||
| e.stopPropagation(); | ||
| setManageOpen(true); | ||
| } | ||
| }} | ||
| className="rounded border border-zinc-800 px-1.5 py-0.5 text-xs text-zinc-400 transition hover:border-zinc-600 hover:text-zinc-200" | ||
| > | ||
| manage | ||
| </span> |
Comment on lines
+31
to
+47
| <div | ||
| role="tab" | ||
| aria-selected={active} | ||
| aria-disabled={disabled || undefined} | ||
| className={ | ||
| "inline-flex shrink-0 items-center gap-2 rounded-t border-b-2 px-3 py-1.5 text-sm font-medium transition " + | ||
| (disabled | ||
| ? "cursor-not-allowed border-transparent text-zinc-700" | ||
| : active | ||
| ? "border-sky-500 bg-zinc-900/40 text-zinc-100" | ||
| : "cursor-pointer border-transparent text-zinc-500 hover:text-zinc-200") | ||
| } | ||
| onClick={() => { | ||
| if (disabled) return; | ||
| onClick(); | ||
| }} | ||
| > |
Comment on lines
+97
to
+107
| <div | ||
| role="tab" | ||
| aria-selected={active} | ||
| title={payload.playbook_id} | ||
| onClick={onClick} | ||
| className={ | ||
| "inline-flex shrink-0 max-w-[14ch] items-center gap-1 rounded-t border-b-2 px-3 py-1.5 text-sm font-medium transition cursor-pointer " + | ||
| (active | ||
| ? "border-sky-500 bg-zinc-900/40 text-zinc-100" | ||
| : "border-transparent text-zinc-500 hover:text-zinc-200") | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
The
frontend/components/directory had ~57 files sitting flat at the top level and several files too large to navigate (SessionView.tsxat 1734 lines,PlaybookEditor.tsxat 1932,Sidebar.tsxat 1284, and more). This PR reorganizes the directory into feature-based folders that mirror the app's route groups, and breaks the ten largest files into co-located sibling files — so a human reader can find things by feature and read any one file in a screen or two. Pure structural refactor: no behavior changes.Changes
shared,layout,investigations,watches,playbooks,repos,codefix,connections,mcp,docs) alongside the existingsessions/wiki/inputs, dissolving the single-fileproposal/folder intoplaybooks/. Files moved withgit mvso history follows them.@/components/<folder>/<Name>alias (previously a mix of relative and alias forms), so each import shows its full location.PlaybookEditor1932→1538,SessionView1734→1160,Sidebar1284→583,NodeEditor754→163,PlaybookGraph622→169,LinkedReposPanel601→117,DocsView517→185.Testing
npm run typecheckis clean, the full frontend vitest suite passes (225 tests across 34 files),make frontendproduces the Next.js static export and re-syncs the embedded bundle, and the Go binaries compile against the regeneratedinternal/web/dist. All extractions are verbatim moves — no logic was changed — and the two commits separate the mechanical move/rewrite (reviewable as renames + import edits) from the file splits.