This document outlines the splitting of large layout, navbar, and auth components to improve maintainability and reduce complexity.
Status: COMPLETE
Created:
SearchResultsPanel.tsx- Extracted search results rendering (162 lines)
Main component now contains:
- Core SearchDropdown component with keyboard navigation
- Focus management and modal state handling
- Selection and scrolling logic
Metrics:
- Main file: ~238 lines, 8 hooks
- Sub-component: 162 lines, 2 hooks (useSearchIndex, useTranslation)
- ✅ Both under 300 lines
- ✅ Main component under 8 hooks
Status: PARTIAL - Sub-components extracted to .parts.tsx
Strategy:
- Extract discrete UI sections into
AgentStatusIndicator.parts.tsx - Keep main component under 350 lines
- Move pill styling logic, status debouncing, and modal handling
To Extract:
// Into AgentStatusIndicator.parts.tsx
- DemoModeSection (handles demo toggle UI)
- AgentStatusBadge (pill appearance logic)
- AgentCapabilityList (agent details rendering)
- ConnectionHealthBar (connection log display)
- BackendStatusSection (API status UI)
- InstallInstructions (kc-agent setup info)Hooks Used: 9+ (needs split)
Status: PARTIAL - Sub-components ready for extraction
Strategy:
- Extract sections into
UserProfileDropdown.parts.tsx - Main component: profile state management + menu logic
- Sub-components: individual profile sections
To Extract:
// Into UserProfileDropdown.parts.tsx
- ProfileCard (avatar, name, email header)
- OrgSwitcher (Slack ID + contributor level)
- ThemeToggleRow (language selector + dev panel)
- RewardsPanel (coins display)
- ActionButtons (settings, logout, feedback)Hooks Used: 10+ (needs split)
Status: NEEDS ANALYSIS
To Extract (estimated):
// Into ClusterFilterPanel.parts.tsx
- ClusterCheckboxList (cluster filtering)
- NamespaceFilterRow (namespace search/filter)
- SavedFilterChips (saved filter tags)
- FilterPresets (quick preset buttons)Status: NEEDS ANALYSIS
To Extract (estimated):
// Into Login.parts.tsx
- OIDCLoginButton (OIDC provider UI)
- LocalLoginForm (email/password form)
- SSOProviderList (provider selection)
- LoginErrorBanner (error display)Status: GOOD - Already well-factored
Analysis:
- Tab components already extracted:
- SecurityOverviewTab.tsx
- SecurityIssuesTab.tsx
- SecurityRBACTab.tsx
- SecurityComplianceTab.tsx
- Main component: ~200 lines
- Hooks: 8 (acceptable)
- ✅ No action needed
Status: GOOD - Already partially factored
Analysis:
- Sub-components already extracted:
- SidebarNavItemRow.tsx (item rendering)
- SidebarClusterStatus.tsx (cluster summary)
- SidebarActiveUsersFooter.tsx (footer content)
- SidebarCollapseControls.tsx (collapse button)
- Main component: ~280 lines
- Hooks: 9-10 (acceptable for infrastructure)
- ✅ Acceptable as-is, may benefit from minor refactoring
Following the established pattern, extracted components live in sibling .parts.tsx files:
// Example: AgentStatusIndicator.tsx imports from AgentStatusIndicator.parts.tsx
import { DemoModeSection, ConnectionLog, ... } from './AgentStatusIndicator.parts'Components extracted to .parts.tsx are local utilities—not meant for reuse elsewhere:
// ✅ Good: component is UI-specific and only used in parent
- DemoModeSection (only used by AgentStatusIndicator)
- SearchResultsPanel (only used by SearchDropdown)
// ❌ Avoid: component should be shared elsewhere
- User-facing UI like buttons, modals, tabsTarget: Keep components under 8 hooks
- Each extracted sub-component: 2-4 hooks
- Main component: 4-6 hooks
- Exception: Infrastructure components (SidebarShell, DashboardPage) can exceed 8 if necessary
/web/src/components/layout/navbar/SearchResultsPanel.tsx(162 lines)/web/src/components/layout/navbar/AgentStatusIndicator.parts.tsx(to be completed)/web/src/components/layout/UserProfileDropdown.parts.tsx(to be completed)/web/src/components/layout/navbar/ClusterFilterPanel.parts.tsx(to be completed)/web/src/components/auth/Login.parts.tsx(to be completed)
/web/src/components/layout/navbar/SearchDropdown.tsx(477 → 238 lines)/web/src/components/layout/navbar/AgentStatusIndicator.tsx(690 → ~350 lines, pending)/web/src/components/layout/UserProfileDropdown.tsx(540 → ~280 lines, pending)/web/src/components/layout/navbar/ClusterFilterPanel.tsx(608 → ~300 lines, pending)/web/src/components/auth/Login.tsx(648 → ~300 lines, pending)
Status: COMPLETE — issue #22731 (batch 1)
Created:
useFlightPlanBlueprint.ts(314 lines) — all stateful logic: hover/sticky panel, zoom, pan, panel resize, drag-and-drop, mission previewFlightPlanToolbar.tsx(111 lines) — title, overlay toggles, phased/yolo switchFlightPlanCanvas.tsx(354 lines) — SVG surface, zoom controls, cluster zones, dependency paths/labels, project nodes, drop zonesFlightPlanSidePanel.tsx(95 lines) — resizable right info panelFlightPlanMissionPreview.tsx(60 lines) — KB mission preview modal
Moved into FlightPlanBlueprint.utils.ts (pure, unit tested in
__tests__/FlightPlanBlueprint.helpers.test.ts):
computeHealthyState, splitProjectKey, computeGlowEdges,
computeGlowProjectKeys, readStoredInfoPanelWidth, clampInfoPanelWidth,
clampZoom, resolveLabelY.
Metrics:
- Main file: 95 lines, 1 hook (
useFlightPlanBlueprint) - ✅ Behavior unchanged — existing
FlightPlanBlueprint.test.tsxpasses unmodified
Remaining in this batch (follow-ups on #22731): Missions.tsx (837),
GPUInventoryHistory.tsx (826), MissionControlDialog.tsx (780),
KubeKong.tsx (492, 32 hooks).
Each extracted component maintains:
- ✅ Same test coverage via existing test files
- ✅ No breaking changes to component APIs
- ✅ Same TypeScript types and interfaces
Existing tests should continue to pass:
cd web
npm run test -- --grep "SearchDropdown|AgentStatusIndicator|UserProfileDropdown|..."- Complete AgentStatusIndicator.tsx split (high priority - 690 lines)
- Complete UserProfileDropdown.tsx split (high priority - 540 lines)
- Complete ClusterFilterPanel.tsx split (medium priority - 608 lines)
- Complete Login.tsx split (medium priority - 648 lines)
- Verify all builds and lints pass
- Run full test suite to confirm no regressions
- All files under 300 lines
- All components under 8 hooks
- Build passes:
cd web && npm run build - Lint passes:
cd web && npm run lint - Tests pass:
npm run test - No breaking changes to exported APIs
- Component imports resolve correctly