Build in the review tool.
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
import type { DiffFile } from '../types';
|
||||
import { ConfirmDialog } from './ConfirmDialog';
|
||||
import { Icon } from './Icon';
|
||||
|
||||
// A diff the server refused to hand over unasked, because rendering it would
|
||||
// wedge the page (see git.Repo.Diff). Two shapes, both built from the file
|
||||
// summary that came back in its place:
|
||||
//
|
||||
// - OversizeWarning — the modal that asks, put up as soon as the diff lands.
|
||||
// - OversizeNotice — what stands in for the diff afterwards, so a dismissed
|
||||
// warning doesn't leave an empty screen with no way back.
|
||||
//
|
||||
// The size is nearly always a base ref whose history has moved on rather than a
|
||||
// genuinely enormous review, so both of them point at the base and at what to
|
||||
// switch to.
|
||||
|
||||
const n = (x: number) => x.toLocaleString();
|
||||
|
||||
// sizeLine describes the change set in one phrase: "412 files, 87,204 changed
|
||||
// lines". Binary files count for no lines, so the file count carries them.
|
||||
function sizeLine(files: DiffFile[]): string {
|
||||
const lines = files.reduce((total, f) => total + f.additions + f.deletions, 0);
|
||||
return `${n(files.length)} file${files.length === 1 ? '' : 's'}, ${n(lines)} changed line${
|
||||
lines === 1 ? '' : 's'
|
||||
}`;
|
||||
}
|
||||
|
||||
// commitAdvice points at the other way through a change set too big to render:
|
||||
// the commits are listed in the left rail whether or not the patch loaded, and
|
||||
// one of them at a time costs nothing.
|
||||
function commitAdvice(commits: number): string | null {
|
||||
if (commits === 0) return null;
|
||||
return (
|
||||
'The commits it spans are listed in the left rail — reading one at a time ' +
|
||||
'renders only that commit, however big the whole range is.'
|
||||
);
|
||||
}
|
||||
|
||||
// advice suggests the way out, which depends on what the base already is.
|
||||
function advice(base: string, suggested: string): string {
|
||||
if (base === 'HEAD') {
|
||||
return 'That is a lot of uncommitted work for one screen.';
|
||||
}
|
||||
const alternative = suggested && suggested !== base ? `${suggested}, or HEAD` : 'HEAD';
|
||||
return (
|
||||
`A diff this size usually means ${base} has moved on since this work was ` +
|
||||
`cut from it, so the change set is padded with commits nobody is reviewing. ` +
|
||||
`Switching the base to ${alternative} will show only the work itself.`
|
||||
);
|
||||
}
|
||||
|
||||
export function OversizeWarning({
|
||||
files,
|
||||
base,
|
||||
suggested,
|
||||
commits,
|
||||
onLoad,
|
||||
onCancel,
|
||||
}: {
|
||||
files: DiffFile[];
|
||||
base: string;
|
||||
suggested: string;
|
||||
commits: number;
|
||||
onLoad: () => void;
|
||||
onCancel: () => void;
|
||||
}) {
|
||||
return (
|
||||
<ConfirmDialog
|
||||
title="This diff is very large"
|
||||
confirmLabel="Load it anyway"
|
||||
onConfirm={onLoad}
|
||||
onCancel={onCancel}
|
||||
>
|
||||
<p>
|
||||
<code>{base}</code> gives <strong>{sizeLine(files)}</strong>. Rendering
|
||||
that much at once can leave the page unresponsive for a while.
|
||||
</p>
|
||||
<p>{advice(base, suggested)}</p>
|
||||
{commitAdvice(commits) && <p>{commitAdvice(commits)}</p>}
|
||||
</ConfirmDialog>
|
||||
);
|
||||
}
|
||||
|
||||
export function OversizeNotice({
|
||||
files,
|
||||
base,
|
||||
suggested,
|
||||
commits,
|
||||
onLoad,
|
||||
}: {
|
||||
files: DiffFile[];
|
||||
base: string;
|
||||
suggested: string;
|
||||
commits: number;
|
||||
onLoad: () => void;
|
||||
}) {
|
||||
return (
|
||||
<div className="oversize-notice">
|
||||
<Icon name="alert" size={20} />
|
||||
<h2>Diff not loaded</h2>
|
||||
<p>
|
||||
<code>{base}</code> gives {sizeLine(files)} — enough to make the page
|
||||
unresponsive, so it wasn’t rendered.
|
||||
</p>
|
||||
<p>{advice(base, suggested)}</p>
|
||||
{commitAdvice(commits) && <p>{commitAdvice(commits)}</p>}
|
||||
<button className="btn-ghost" onClick={onLoad}>
|
||||
Load it anyway
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user