Files
pterodactyl_addon/resources/scripts/addons/advanced-admin/revisions/DiffViewer.tsx
2026-06-11 20:37:13 -05:00

67 lines
2.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Diff Viewer — unified diff with syntax coloring
* Ball Studios <https://git.balls.studio>
*/
import React, { useEffect, useState } from 'react';
import http from '@/api/http';
interface DiffLine {
type: 'context' | 'added' | 'removed' | 'header';
content: string;
line_old?: number;
line_new?: number;
}
interface Props {
serverUuid: string;
revision: { id: number; revision_number: number };
onClose: () => void;
}
export default function DiffViewer({ serverUuid, revision, onClose }: Props) {
const [lines, setLines] = useState<DiffLine[]>([]);
const [binary, setBinary] = useState(false);
const [loading, setLoading] = useState(true);
useEffect(() => {
http.get<{ binary: boolean; lines: DiffLine[] }>(`/api/client/servers/${serverUuid}/addons/files/revisions/${revision.id}/diff`)
.then(({ data }: { data: { binary: boolean; lines: DiffLine[] } }) => {
setBinary(data.binary);
setLines(data.lines ?? []);
})
.finally(() => setLoading(false));
}, [serverUuid, revision.id]);
return (
<div className='addon-modal-overlay' onClick={(_e: React.MouseEvent) => onClose()} role='dialog' aria-modal='true'>
<div className='addon-modal addon-modal-wide' onClick={(e: React.MouseEvent) => e.stopPropagation()}>
<div className='addon-modal-header'>
<span>Diff Revision #{revision.revision_number}</span>
<button className='addon-modal-close' onClick={onClose} aria-label='Close'></button>
</div>
{loading && <div className='addon-loading'>Loading diff</div>}
{!loading && binary && <div className='addon-empty'>Binary file diff not available.</div>}
{!loading && !binary && (
<pre className='addon-diff'>
{lines.map((line: DiffLine, i: number) => (
<div
key={i}
className={`addon-diff-line addon-diff-${line.type}`}
>
<span className='addon-diff-lnum'>
{line.line_old ?? ' '} {line.line_new ?? ' '}
</span>
<span className='addon-diff-sign'>
{line.type === 'added' ? '+' : line.type === 'removed' ? '' : ' '}
</span>
{line.content}
</div>
))}
</pre>
)}
</div>
</div>
);
}