Skip to content

Commit 13dee70

Browse files
refactor: reduce complexity in agent.py, App.tsx, TopologyView.tsx
- research/agent.py: split tool-creation functions into individual builders - App.tsx: fix S6754, S2681, S6848, extract helper - TopologyView.tsx: extract applyElkLayout to module level
1 parent 6651650 commit 13dee70

File tree

3 files changed

+1009
-944
lines changed

3 files changed

+1009
-944
lines changed

apps/web/src/App.tsx

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,8 @@ function App() {
512512
const [editCollectionLoading, setEditCollectionLoading] = useState(false)
513513

514514
// Sources state
515-
const [_sources, setSources] = useState<Source[]>([])
515+
const [sources, setSources] = useState<Source[]>([])
516+
void sources // used via setSources; value read by child components via collectionSources
516517
const [newSourceType, setNewSourceType] = useState<'github' | 'web'>('github')
517518
const [newSourceUrl, setNewSourceUrl] = useState('')
518519
const [newSourceEnabled, setNewSourceEnabled] = useState(true)
@@ -1836,17 +1837,19 @@ function App() {
18361837
</div>
18371838
)}
18381839

1839-
{collectionsLoading ? (
1840+
{collectionsLoading && (
18401841
<p className="loading-text">Loading collections...</p>
1841-
) : collections.length === 0 ? (
1842+
)}
1843+
{!collectionsLoading && collections.length === 0 && (
18421844
<div className="empty-state">
18431845
<p>No collections yet</p>
18441846
<p className="note">Collections organize your documentation and code sources.</p>
18451847
<button className="create-button" onClick={() => setSelectedCollection({ id: 'new' } as Collection)}>
18461848
Create Your First Collection
18471849
</button>
18481850
</div>
1849-
) : (
1851+
)}
1852+
{!collectionsLoading && collections.length > 0 && (
18501853
<div className="collections-list">
18511854
{collections.map((collection) => {
18521855
const isExpanded = expandedCollections.has(collection.id)
@@ -1859,7 +1862,7 @@ function App() {
18591862
return (
18601863
<div key={collection.id} className={`collection-row ${isExpanded ? 'expanded' : ''}`}>
18611864
{/* Collection Header Row */}
1862-
<div className="collection-header-row" role="button" tabIndex={0} onClick={(e) => { if (!(e.target as HTMLElement).closest('form, [role="toolbar"]')) { handleToggleExpand(collection) } }} onKeyDown={e => { if (e.key === 'Enter') { handleToggleExpand(collection) } }}>
1865+
<div className="collection-header-row" role="button" tabIndex={0} aria-label={`Toggle collection ${collection.name}`} onClick={(e) => { if (!(e.target as HTMLElement).closest('form, [role="toolbar"]')) { handleToggleExpand(collection) } }} onKeyDown={e => { if (e.key === 'Enter') { handleToggleExpand(collection) } }}>
18631866
<button className="expand-toggle" aria-label={isExpanded ? 'Collapse' : 'Expand'}>
18641867
{isExpanded ? '▼' : '▶'}
18651868
</button>
@@ -1958,7 +1961,7 @@ function App() {
19581961

19591962
{/* Share Popover */}
19601963
{sharePopoverCollection?.id === collection.id && (
1961-
<div className="share-popover" role="dialog" onClick={e => e.stopPropagation()} onKeyDown={e => e.stopPropagation()}>
1964+
<dialog open className="share-popover" aria-label={`Share ${collection.name}`}>
19621965
<div className="popover-header">
19631966
<h4>Share "{collection.name}"</h4>
19641967
<button className="close-btn" onClick={handleCloseSharePopover}>×</button>
@@ -1992,7 +1995,7 @@ function App() {
19921995
</form>
19931996
{shareError && <p className="share-error-mini">{shareError}</p>}
19941997
</div>
1995-
</div>
1998+
</dialog>
19961999
)}
19972000

19982001
{/* Expanded Sources Section */}

apps/web/src/cockpit/views/TopologyView.tsx

Lines changed: 54 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,21 @@ import ReactFlow, {
1111
import ViewShell from '../components/ViewShell'
1212
import { runElkLayout, runGridLayout, type LayoutEngine } from '../layout/layoutCore'
1313

14+
interface ElkLayoutParams {
15+
nodes: Array<{ id: string }>
16+
edges: Array<{ source: string; target: string }>
17+
engine: LayoutEngine
18+
columns: number
19+
cancelled: { current: boolean }
20+
startedAt: number
21+
onPositions: (positions: Record<string, { x: number; y: number }>) => void
22+
onCompleted: (engine: LayoutEngine, durationMs: number, nodeCount: number) => void
23+
onFinish: () => void
24+
}
25+
1426
/** Run ELK layout (in-thread or via worker), calling back with positions on completion. */
15-
async function applyElkLayout(
16-
nodes: Array<{ id: string }>,
17-
edges: Array<{ source: string; target: string }>,
18-
engine: LayoutEngine,
19-
columns: number,
20-
cancelled: { current: boolean },
21-
startedAt: number,
22-
onPositions: (positions: Record<string, { x: number; y: number }>) => void,
23-
onCompleted: (engine: LayoutEngine, durationMs: number, nodeCount: number) => void,
24-
onFinish: () => void,
25-
): Promise<void> {
27+
async function applyElkLayout(params: Readonly<ElkLayoutParams>): Promise<void> {
28+
const { nodes, edges, engine, columns, cancelled, startedAt, onPositions, onCompleted, onFinish } = params
2629
try {
2730
if (nodes.length > 1000) {
2831
const worker = new Worker(new URL('../layout/layoutWorker.ts', import.meta.url), {
@@ -88,6 +91,35 @@ function overlayColorForNode(overlay: OverlayState, naturalKey: string, fallback
8891
return '#1d4ed8'
8992
}
9093

94+
function buildRFNode(
95+
node: TwinGraphResponse['nodes'][number],
96+
index: number,
97+
overlay: OverlayState,
98+
selectedNodeId: string,
99+
layoutPositions: Record<string, { x: number; y: number }>,
100+
columns: number,
101+
showLabels: boolean,
102+
): RFNode {
103+
const runtime = overlay.runtimeByNodeKey[node.natural_key] || overlay.runtimeByNodeKey[node.name]
104+
const isSelected = selectedNodeId === node.id
105+
const position = layoutPositions[node.id] || { x: (index % columns) * 260, y: Math.floor(index / columns) * 130 }
106+
const nodeOpacity = overlay.mode === 'runtime' && runtime?.error_rate === undefined ? 0.84 : 1
107+
return {
108+
id: node.id,
109+
data: { label: showLabels ? node.name : '' },
110+
position,
111+
style: {
112+
width: 210,
113+
fontSize: 11,
114+
borderRadius: 10,
115+
border: isSelected ? '2px solid #f59e0b' : `1px solid ${overlayColorForNode(overlay, node.natural_key, node.name)}`,
116+
background: '#ffffff',
117+
boxShadow: isSelected ? '0 0 0 3px rgba(245, 158, 11, 0.22)' : 'none',
118+
opacity: nodeOpacity,
119+
},
120+
}
121+
}
122+
91123
export default function TopologyView({
92124
graph,
93125
state,
@@ -134,44 +166,24 @@ export default function TopologyView({
134166
}
135167

136168
const cancelRef = { current: false }
137-
applyElkLayout(
138-
graph.nodes.map((node) => ({ id: node.id })),
139-
graph.edges.map((edge) => ({ source: edge.source_node_id, target: edge.target_node_id })),
140-
preferredEngine,
169+
applyElkLayout({
170+
nodes: graph.nodes.map((node) => ({ id: node.id })),
171+
edges: graph.edges.map((edge) => ({ source: edge.source_node_id, target: edge.target_node_id })),
172+
engine: preferredEngine,
141173
columns,
142-
cancelRef,
143-
performance.now(),
144-
setLayoutPositions,
145-
onLayoutCompleted,
146-
() => setLayoutStatus('refined'),
147-
)
174+
cancelled: cancelRef,
175+
startedAt: performance.now(),
176+
onPositions: setLayoutPositions,
177+
onCompleted: onLayoutCompleted,
178+
onFinish: () => setLayoutStatus('refined'),
179+
})
148180
return () => {
149181
cancelRef.current = true
150182
}
151183
}, [graph.edges, graph.nodes, columns, preferredEngine, onLayoutCompleted])
152184

153185
const nodes = useMemo<RFNode[]>(() => {
154-
return graph.nodes.map((node, index) => {
155-
const runtime = overlay.runtimeByNodeKey[node.natural_key] || overlay.runtimeByNodeKey[node.name]
156-
const isSelected = selectedNodeId === node.id
157-
const position = layoutPositions[node.id] || { x: (index % columns) * 260, y: Math.floor(index / columns) * 130 }
158-
return {
159-
id: node.id,
160-
data: {
161-
label: showLabels ? node.name : '',
162-
},
163-
position,
164-
style: {
165-
width: 210,
166-
fontSize: 11,
167-
borderRadius: 10,
168-
border: isSelected ? '2px solid #f59e0b' : `1px solid ${overlayColorForNode(overlay, node.natural_key, node.name)}`,
169-
background: '#ffffff',
170-
boxShadow: isSelected ? '0 0 0 3px rgba(245, 158, 11, 0.22)' : 'none',
171-
opacity: overlay.mode === 'runtime' && runtime?.error_rate === undefined ? 0.84 : 1,
172-
},
173-
}
174-
})
186+
return graph.nodes.map((node, index) => buildRFNode(node, index, overlay, selectedNodeId, layoutPositions, columns, showLabels))
175187
}, [graph.nodes, showLabels, layoutPositions, columns, overlay, selectedNodeId])
176188

177189
const edges = useMemo<RFEdge[]>(() => {

0 commit comments

Comments
 (0)