mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-09-30 01:51:20 +00:00
fix(web): address four more PR review comments
Edge visibility (useSigma.ts): HAS_METHOD / HAS_PROPERTY edges were hidden when any edge-type filter was active because those types are not in the EdgeType union. Normalize HAS_METHOD → DEFINES and HAS_PROPERTY → CONTAINS before the visibleTypes.includes() guard so Kotlin/Java hierarchy edges follow the same filter logic as their semantic equivalents. Force-mode edge styles (graph-adapter.ts): HAS_METHOD / HAS_PROPERTY fell back to the default gray color in the force-graph adapter because EDGE_STYLES had no entries for them. Added explicit entries using the same hues as DEFINES/CONTAINS so force mode renders Kotlin/Java hierarchy edges consistently with tree/circles. Accessibility (GraphCanvas.tsx, locales): the layout-mode switcher (Force / Tree / Circles) had no ARIA semantics. Added role="tablist" on the container and role="tab" + aria-selected on each button. Added the viewModes.label i18n key (used as aria-label on the tablist) to en and zh-CN locale files. Flaky test (graph-adapter.test.ts): replaced the hard 2 s wall-clock assertion with a structural check (node count + edge count) that is deterministic across CI hardware. Timing tests are inherently flaky and provide no correctness signal. Co-authored-by: Claude <noreply@anthropic.com> AI-model: claude-sonnet-4-5
This commit is contained in:
parent
743a69c5ff
commit
4e5df3d3c8
6 changed files with 38 additions and 9 deletions
|
|
@ -272,8 +272,14 @@ export const GraphCanvas = forwardRef<GraphCanvasHandle>((_, ref) => {
|
|||
</div>
|
||||
|
||||
{/* View Mode Tabs */}
|
||||
<div className="absolute top-4 left-1/2 z-20 flex -translate-x-1/2 gap-1 rounded-lg border border-border-subtle bg-elevated/90 p-1 backdrop-blur-sm">
|
||||
<div
|
||||
role="tablist"
|
||||
aria-label={t('canvas.viewModes.label')}
|
||||
className="absolute top-4 left-1/2 z-20 flex -translate-x-1/2 gap-1 rounded-lg border border-border-subtle bg-elevated/90 p-1 backdrop-blur-sm"
|
||||
>
|
||||
<button
|
||||
role="tab"
|
||||
aria-selected={graphViewMode === 'force'}
|
||||
onClick={() => handleViewModeChange('force')}
|
||||
className={`flex items-center gap-1.5 rounded-md px-3 py-1.5 text-xs font-medium transition-all ${
|
||||
graphViewMode === 'force'
|
||||
|
|
@ -285,6 +291,8 @@ export const GraphCanvas = forwardRef<GraphCanvasHandle>((_, ref) => {
|
|||
{t('canvas.viewModes.force')}
|
||||
</button>
|
||||
<button
|
||||
role="tab"
|
||||
aria-selected={graphViewMode === 'tree'}
|
||||
onClick={() => handleViewModeChange('tree')}
|
||||
className={`flex items-center gap-1.5 rounded-md px-3 py-1.5 text-xs font-medium transition-all ${
|
||||
graphViewMode === 'tree'
|
||||
|
|
@ -296,6 +304,8 @@ export const GraphCanvas = forwardRef<GraphCanvasHandle>((_, ref) => {
|
|||
{t('canvas.viewModes.tree')}
|
||||
</button>
|
||||
<button
|
||||
role="tab"
|
||||
aria-selected={graphViewMode === 'circles'}
|
||||
onClick={() => handleViewModeChange('circles')}
|
||||
className={`flex items-center gap-1.5 rounded-md px-3 py-1.5 text-xs font-medium transition-all ${
|
||||
graphViewMode === 'circles'
|
||||
|
|
|
|||
|
|
@ -586,10 +586,19 @@ export const useSigma = (options: UseSigmaOptions = {}): UseSigmaReturn => {
|
|||
edgeReducer: (edge, data) => {
|
||||
const res = { ...data };
|
||||
|
||||
// Check edge type visibility first
|
||||
// Check edge type visibility first.
|
||||
// HAS_METHOD / HAS_PROPERTY are Kotlin/Java hierarchy edges not in the
|
||||
// EdgeType union — normalize them so they follow DEFINES / CONTAINS
|
||||
// visibility instead of being silently hidden.
|
||||
const visibleTypes = visibleEdgeTypesRef.current;
|
||||
if (visibleTypes && data.relationType) {
|
||||
if (!visibleTypes.includes(data.relationType as EdgeType)) {
|
||||
const normalizedType =
|
||||
data.relationType === 'HAS_METHOD'
|
||||
? 'DEFINES'
|
||||
: data.relationType === 'HAS_PROPERTY'
|
||||
? 'CONTAINS'
|
||||
: data.relationType;
|
||||
if (!visibleTypes.includes(normalizedType as EdgeType)) {
|
||||
res.hidden = true;
|
||||
return res;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,8 +98,9 @@ describe('knowledgeGraphToTreeGraphology', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should complete within an acceptable time budget for a medium-sized graph', () => {
|
||||
it('should handle a medium-sized graph without dropping nodes or edges', () => {
|
||||
// 2000 nodes + 4000 edges — exercises the adaptive spring iteration path (14 iters).
|
||||
// Structural assertion only: wall-clock timing is too variable across CI machines.
|
||||
const nodes: GraphNode[] = Array.from({ length: 2000 }, (_, i) =>
|
||||
makeNode(`n${i}`, i % 4 === 0 ? 'Folder' : i % 4 === 1 ? 'File' : 'Function', `node${i}`),
|
||||
);
|
||||
|
|
@ -111,12 +112,14 @@ describe('knowledgeGraphToTreeGraphology', () => {
|
|||
}));
|
||||
const graph: KnowledgeGraph = { nodes, relationships };
|
||||
|
||||
const start = performance.now();
|
||||
knowledgeGraphToTreeGraphology(graph);
|
||||
const elapsed = performance.now() - start;
|
||||
const sigmaGraph = knowledgeGraphToTreeGraphology(graph);
|
||||
|
||||
// Should complete comfortably within 2 seconds even on slow CI machines.
|
||||
expect(elapsed).toBeLessThan(2000);
|
||||
// All nodes that have a tree-layout position must be present in the output.
|
||||
expect(sigmaGraph.order).toBe(2000);
|
||||
// Every relationship whose source and target both exist should produce an edge.
|
||||
// Self-loops (sourceId === targetId) are excluded — the adapter skips them.
|
||||
const selfLoops = relationships.filter((r) => r.sourceId === r.targetId).length;
|
||||
expect(sigmaGraph.size).toBe(relationships.length - selfLoops);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -308,6 +308,11 @@ export const knowledgeGraphToGraphology = (
|
|||
// TYPE RELATIONSHIPS - Warm colors (OOP)
|
||||
EXTENDS: { color: '#c2410c', sizeMultiplier: 1.0 }, // Orange - extension
|
||||
IMPLEMENTS: { color: '#be185d', sizeMultiplier: 0.9 }, // Pink - interface implementation
|
||||
|
||||
// KOTLIN/JAVA HIERARCHY — same hues as their logical equivalents so force
|
||||
// mode renders these consistently with tree/circles view.
|
||||
HAS_METHOD: { color: EDGE_INFO.DEFINES.color, sizeMultiplier: 0.4 }, // Class→Method (≈ DEFINES)
|
||||
HAS_PROPERTY: { color: EDGE_INFO.CONTAINS.color, sizeMultiplier: 0.35 }, // Class→Property (≈ CONTAINS)
|
||||
};
|
||||
|
||||
// Two-pass insertion so hierarchy/DEFINES edges are drawn first (behind)
|
||||
|
|
|
|||
|
|
@ -113,6 +113,7 @@
|
|||
},
|
||||
"canvas": {
|
||||
"viewModes": {
|
||||
"label": "Graph view mode",
|
||||
"force": "Force Graph",
|
||||
"tree": "Sequential Layout",
|
||||
"circles": "Radial Layout"
|
||||
|
|
|
|||
|
|
@ -113,6 +113,7 @@
|
|||
},
|
||||
"canvas": {
|
||||
"viewModes": {
|
||||
"label": "图形视图模式",
|
||||
"force": "力导向图",
|
||||
"tree": "顺序布局",
|
||||
"circles": "径向布局"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue