Skip to content

Commit 7fd3a4c

Browse files
committed
Improve WEB UI
1 parent 2557443 commit 7fd3a4c

File tree

1 file changed

+83
-70
lines changed

1 file changed

+83
-70
lines changed

nextjs-frontend/src/components/diff/BeyondCompareFunctionDiff.tsx

Lines changed: 83 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ const UnifiedDiffView: React.FC<DiffViewProps> = ({
5151
const [lineDiffs, setLineDiffs] = React.useState<LineDiff[]>([]);
5252
const [loading, setLoading] = React.useState(true);
5353
const [viewMode, setViewMode] = React.useState<ViewMode>('unified');
54-
const [diffAlgorithm, setDiffAlgorithm] = React.useState<DiffAlgorithm>('lcs');
54+
const [diffAlgorithm, setDiffAlgorithm] = React.useState<DiffAlgorithm>('ast');
5555
const scrollContainerRef = React.useRef<HTMLDivElement>(null);
5656

5757
React.useEffect(() => {
@@ -60,7 +60,7 @@ const UnifiedDiffView: React.FC<DiffViewProps> = ({
6060
setLoading(true);
6161

6262
// Call the Rust backend AST diff API
63-
const response = await fetch('http://localhost:8080/api/ast-diff', {
63+
const response = await fetch('http://localhost:8080/api/ast/diff', {
6464
method: 'POST',
6565
headers: { 'Content-Type': 'application/json' },
6666
body: JSON.stringify({
@@ -81,7 +81,9 @@ const UnifiedDiffView: React.FC<DiffViewProps> = ({
8181
});
8282

8383
if (!response.ok) {
84-
throw new Error('Failed to fetch diff');
84+
const errorText = await response.text();
85+
console.warn('AST diff API failed, falling back to simple diff:', response.status, errorText);
86+
throw new Error(`Failed to fetch diff: ${response.statusText}`);
8587
}
8688

8789
const data = await response.json();
@@ -97,7 +99,7 @@ const UnifiedDiffView: React.FC<DiffViewProps> = ({
9799

98100
setLineDiffs(diffs);
99101
} catch (error) {
100-
console.error('Error fetching diff:', error);
102+
console.info('Using fallback diff algorithm (AST backend not available)');
101103
// Fallback to simple line-by-line comparison
102104
const sourceLines = sourceContent.split('\n');
103105
const targetLines = targetContent.split('\n');
@@ -251,8 +253,84 @@ const UnifiedDiffView: React.FC<DiffViewProps> = ({
251253
</div>
252254
</div>
253255

254-
{/* Unified View */}
256+
{/* Unified View - Traditional single-column diff */}
255257
{viewMode === 'unified' && (
258+
<div
259+
ref={scrollContainerRef}
260+
className="overflow-auto max-h-[600px] bg-slate-900"
261+
style={{ scrollbarGutter: 'stable' }}
262+
>
263+
<div>
264+
{lineDiffs.map((diff, idx) => {
265+
// For unified view, show each line with +/- prefix
266+
const showSourceLine = diff.sourceLineNum !== null && diff.type !== 'added';
267+
const showTargetLine = diff.targetLineNum !== null && diff.type !== 'deleted';
268+
269+
return (
270+
<React.Fragment key={`unified-${idx}`}>
271+
{/* Show deleted/modified source line with - prefix */}
272+
{showSourceLine && diff.type !== 'unchanged' && (
273+
<div
274+
className={`flex ${getLineBackgroundColor(diff.type === 'modified' ? 'deleted' : diff.type)} ${getLineBorderColor('deleted')}`}
275+
>
276+
<div className="w-12 flex-shrink-0 text-right pr-3 py-1 text-slate-500 text-xs font-mono select-none border-r border-slate-700">
277+
{diff.sourceLineNum}
278+
</div>
279+
<div className="w-8 flex-shrink-0 text-center py-1 text-red-400 text-xs font-mono select-none">
280+
-
281+
</div>
282+
<div className="flex-1 px-3 py-1">
283+
<pre className="font-mono text-sm text-slate-100 whitespace-pre">
284+
{diff.sourceContent}
285+
</pre>
286+
</div>
287+
</div>
288+
)}
289+
290+
{/* Show added/modified target line with + prefix */}
291+
{showTargetLine && diff.type !== 'unchanged' && (
292+
<div
293+
className={`flex ${getLineBackgroundColor(diff.type === 'modified' ? 'added' : diff.type)} ${getLineBorderColor('added')}`}
294+
>
295+
<div className="w-12 flex-shrink-0 text-right pr-3 py-1 text-slate-500 text-xs font-mono select-none border-r border-slate-700">
296+
{diff.targetLineNum}
297+
</div>
298+
<div className="w-8 flex-shrink-0 text-center py-1 text-green-400 text-xs font-mono select-none">
299+
+
300+
</div>
301+
<div className="flex-1 px-3 py-1">
302+
<pre className="font-mono text-sm text-slate-100 whitespace-pre">
303+
{diff.targetContent}
304+
</pre>
305+
</div>
306+
</div>
307+
)}
308+
309+
{/* Show unchanged lines with no prefix */}
310+
{diff.type === 'unchanged' && (
311+
<div className={`flex ${getLineBackgroundColor('unchanged')}`}>
312+
<div className="w-12 flex-shrink-0 text-right pr-3 py-1 text-slate-500 text-xs font-mono select-none border-r border-slate-700">
313+
{diff.sourceLineNum || diff.targetLineNum}
314+
</div>
315+
<div className="w-8 flex-shrink-0 text-center py-1 text-slate-600 text-xs font-mono select-none">
316+
{' '}
317+
</div>
318+
<div className="flex-1 px-3 py-1">
319+
<pre className="font-mono text-sm text-slate-100 whitespace-pre">
320+
{diff.sourceContent || diff.targetContent}
321+
</pre>
322+
</div>
323+
</div>
324+
)}
325+
</React.Fragment>
326+
);
327+
})}
328+
</div>
329+
</div>
330+
)}
331+
332+
{/* Side-by-Side View - Synchronized two-column layout */}
333+
{viewMode === 'side-by-side' && (
256334
<div
257335
ref={scrollContainerRef}
258336
className="overflow-auto max-h-[600px]"
@@ -313,71 +391,6 @@ const UnifiedDiffView: React.FC<DiffViewProps> = ({
313391
</div>
314392
</div>
315393
)}
316-
317-
{/* Side-by-Side View */}
318-
{viewMode === 'side-by-side' && (
319-
<div className="grid grid-cols-2 divide-x divide-slate-700">
320-
{/* Source Code */}
321-
<div className="bg-slate-900">
322-
<div className="sticky top-0 z-10 px-4 py-2 bg-slate-800 border-b border-slate-700">
323-
<span className="text-xs font-medium text-slate-300 uppercase tracking-wide">Source</span>
324-
</div>
325-
<div className="overflow-auto max-h-[600px]">
326-
<div>
327-
{lineDiffs
328-
.filter(diff => diff.sourceLineNum !== null)
329-
.map((diff, idx) => (
330-
<div
331-
key={`source-sbs-${idx}`}
332-
className={`flex ${getLineBackgroundColor(diff.type === 'added' ? 'unchanged' : diff.type)} ${
333-
diff.type === 'deleted' || diff.type === 'modified' ? getLineBorderColor(diff.type) : ''
334-
}`}
335-
>
336-
<div className="w-12 flex-shrink-0 text-right pr-3 py-1 text-slate-500 text-xs font-mono select-none border-r border-slate-700">
337-
{diff.sourceLineNum}
338-
</div>
339-
<div className="flex-1 px-3 py-1">
340-
<pre className="font-mono text-sm text-slate-100 whitespace-pre">
341-
{diff.sourceContent}
342-
</pre>
343-
</div>
344-
</div>
345-
))}
346-
</div>
347-
</div>
348-
</div>
349-
350-
{/* Target Code */}
351-
<div className="bg-slate-900">
352-
<div className="sticky top-0 z-10 px-4 py-2 bg-slate-800 border-b border-slate-700">
353-
<span className="text-xs font-medium text-slate-300 uppercase tracking-wide">Target</span>
354-
</div>
355-
<div className="overflow-auto max-h-[600px]">
356-
<div>
357-
{lineDiffs
358-
.filter(diff => diff.targetLineNum !== null)
359-
.map((diff, idx) => (
360-
<div
361-
key={`target-sbs-${idx}`}
362-
className={`flex ${getLineBackgroundColor(diff.type === 'deleted' ? 'unchanged' : diff.type)} ${
363-
diff.type === 'added' || diff.type === 'modified' ? getLineBorderColor(diff.type) : ''
364-
}`}
365-
>
366-
<div className="w-12 flex-shrink-0 text-right pr-3 py-1 text-slate-500 text-xs font-mono select-none border-r border-slate-700">
367-
{diff.targetLineNum}
368-
</div>
369-
<div className="flex-1 px-3 py-1">
370-
<pre className="font-mono text-sm text-slate-100 whitespace-pre">
371-
{diff.targetContent}
372-
</pre>
373-
</div>
374-
</div>
375-
))}
376-
</div>
377-
</div>
378-
</div>
379-
</div>
380-
)}
381394
</div>
382395
);
383396
};

0 commit comments

Comments
 (0)