From 1d323de11a46cb6ad6c2bbfc0a41726cd63d21cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CBeeRad=E2=80=9D?= Date: Sun, 15 Feb 2026 09:28:01 +1100 Subject: [PATCH] fix: edges tab truncation and layout polish MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add minWidth: 0 on all flex containers to enable proper truncation - Title now truncates with ellipsis instead of pushing panel out - Explanation row truncates to single line with ellipsis and title tooltip - Type chip has flexShrink: 0 + whiteSpace: nowrap to prevent wrapping - Delete button uses compact × with flexShrink: 0 (inline, not separate) - Edit input has minWidth: 0 to prevent overflow - Remove expand/collapse (5-item limit) — show all connections in tab - Tighter spacing (6px padding, 2px gap) matching private repo polish Co-Authored-By: Claude Opus 4.6 --- src/components/focus/FocusPanel.tsx | 378 ++++++++++++++-------------- 1 file changed, 186 insertions(+), 192 deletions(-) diff --git a/src/components/focus/FocusPanel.tsx b/src/components/focus/FocusPanel.tsx index 4514f8c..d1f758b 100644 --- a/src/components/focus/FocusPanel.tsx +++ b/src/components/focus/FocusPanel.tsx @@ -107,7 +107,7 @@ export default function FocusPanel({ openTabs, activeTab, onTabSelect, onNodeCli const [chunkExpanded, setChunkExpanded] = useState<{ [key: number]: boolean }>({}); // Edges expand/collapse state - const [edgesExpanded, setEdgesExpanded] = useState<{ [key: number]: boolean }>({}); + // edgesExpanded removed — all connections shown in Edges tab // Connections section collapsed state (default closed) const [edgeSearchOpen, setEdgeSearchOpen] = useState(false); @@ -1369,208 +1369,202 @@ export default function FocusPanel({ openTabs, activeTab, onTabSelect, onNodeCli )} - {/* Existing Connections */} + {/* Connections List */}
-
- Existing Connections -
{loadingEdges.has(activeTab) ? ( -
Loading connections…
+
Loading connections…
) : (() => { const list = edgesData[activeTab] || []; if (list.length === 0) { - return
No connections yet. Search above to add one.
; + return
No connections yet.
; } - const visible = edgesExpanded[activeTab] ? list : list.slice(0, 5); return ( -
- {visible.map((connection) => ( -
-
-
- {/* Direction arrow: → if current node is FROM (outgoing), ← if current node is TO (incoming) */} - + {list.map((connection) => ( +
+ {/* Row 1: arrow + ID + icon + title + delete */} +
+ + {connection.edge.from_node_id === activeTab ? '→' : '←'} + + + {connection.connected_node.id} + + + {getNodeIcon(connection.connected_node, dimensionIcons, 12)} + + onNodeClick?.(connection.connected_node.id)} + style={{ fontSize: '12px', - color: connection.edge.from_node_id === activeTab ? '#22c55e' : '#f59e0b', - fontWeight: 600, - width: '16px', - textAlign: 'center' - }}> - {connection.edge.from_node_id === activeTab ? '→' : '←'} - - - {connection.connected_node.id} - - - {getNodeIcon(connection.connected_node, dimensionIcons, 12)} - - {connection.connected_node.title} -
- {edgeEditingId === connection.edge.id ? ( -
- setEdgeEditingValue(e.target.value)} - onKeyDown={(e) => { - if (e.key === 'Enter') { - e.preventDefault(); - saveEdgeExplanation(connection.edge.id, connection.edge.context); - } else if (e.key === 'Escape') { - e.preventDefault(); - cancelEditEdgeExplanation(); - } - }} - style={{ - flex: 1, - fontSize: '11px', - color: '#ddd', - background: 'transparent', - border: '1px solid #1a1a1a', - borderRadius: '0', - padding: '4px', - outline: 'none', - fontFamily: 'inherit' - }} - placeholder="Add explanation…" - autoFocus - /> - - -
- ) : ( -
- {typeof connection.edge.context?.type === 'string' && ( - - {String(connection.edge.context.type).replace(/_/g, ' ')} - - )} - {connection.edge.context?.explanation ? ( - - — {connection.edge.context.explanation} - - ) : ( - No explanation - )} - -
- )} + color: '#e5e5e5', + fontWeight: 500, + overflow: 'hidden', + textOverflow: 'ellipsis', + whiteSpace: 'nowrap', + flex: 1, + minWidth: 0, + cursor: 'pointer', + }} + onMouseEnter={(e) => { e.currentTarget.style.color = '#22c55e'; }} + onMouseLeave={(e) => { e.currentTarget.style.color = '#e5e5e5'; }} + > + {connection.connected_node.title} + +
- + {/* Row 2: type chip + explanation (compact, single line) */} + {edgeEditingId === connection.edge.id ? ( +
+ setEdgeEditingValue(e.target.value)} + onKeyDown={(e) => { + if (e.key === 'Enter') { + e.preventDefault(); + saveEdgeExplanation(connection.edge.id, connection.edge.context); + } else if (e.key === 'Escape') { + e.preventDefault(); + cancelEditEdgeExplanation(); + } + }} + style={{ + flex: 1, + fontSize: '11px', + color: '#ddd', + background: '#111', + border: '1px solid #2a2a2a', + borderRadius: '4px', + padding: '3px 6px', + outline: 'none', + fontFamily: 'inherit', + minWidth: 0, + }} + placeholder="Add explanation…" + autoFocus + /> + + +
+ ) : ( +
startEditEdgeExplanation(connection.edge.id, connection.edge.context?.explanation)} + style={{ + display: 'flex', + alignItems: 'center', + gap: '6px', + paddingLeft: '20px', + cursor: 'pointer', + minWidth: 0, + }} + onMouseEnter={(e) => { e.currentTarget.style.opacity = '0.8'; }} + onMouseLeave={(e) => { e.currentTarget.style.opacity = '1'; }} + > + {typeof connection.edge.context?.type === 'string' && ( + + {String(connection.edge.context.type).replace(/_/g, ' ')} + + )} + + {(connection.edge.context?.explanation as string) || 'Add explanation...'} + +
+ )}
))} - {list.length > 5 && ( -
- -
- )}
); })()}