addons/isl/src/ComparisonView/SplitDiffView/SplitDiffRow.tsxblame
View source
b69ab311/**
b69ab312 * Copyright (c) Meta Platforms, Inc. and affiliates.
b69ab313 *
b69ab314 * This source code is licensed under the MIT license found in the
b69ab315 * LICENSE file in the root directory of this source tree.
b69ab316 */
b69ab317
b69ab318import type {ExclusiveOr} from 'shared/typeUtils';
b69ab319import type {OneIndexedLineNumber} from './types';
b69ab3110
b69ab3111type Props = {
b69ab3112 beforeLineNumber: number | null;
b69ab3113 before: React.ReactFragment | null;
b69ab3114 afterLineNumber: number | null;
b69ab3115 after: React.ReactFragment | null;
b69ab3116 rowType: SplitDiffRowType;
b69ab3117 path: string;
b69ab3118 unified: boolean;
b69ab3119 openFileToLine?: (lineNumber: OneIndexedLineNumber) => unknown;
b69ab3120};
b69ab3121
b69ab3122type SplitDiffRowType = 'add' | 'common' | 'modify' | 'remove' | 'expanded';
b69ab3123
b69ab3124export default function SplitDiffRow({
b69ab3125 beforeLineNumber,
b69ab3126 before,
b69ab3127 afterLineNumber,
b69ab3128 after,
b69ab3129 rowType,
b69ab3130 path,
b69ab3131 unified,
b69ab3132 openFileToLine,
b69ab3133}: Props): [JSX.Element, JSX.Element, JSX.Element, JSX.Element] {
b69ab3134 let beforeClass;
b69ab3135 let afterClass;
b69ab3136 switch (rowType) {
b69ab3137 case 'remove':
b69ab3138 beforeClass = 'patch-remove-line';
b69ab3139 afterClass = undefined;
b69ab3140 break;
b69ab3141 case 'modify':
b69ab3142 beforeClass = 'patch-remove-line';
b69ab3143 afterClass = 'patch-add-line';
b69ab3144 break;
b69ab3145 case 'add':
b69ab3146 beforeClass = undefined;
b69ab3147 afterClass = 'patch-add-line';
b69ab3148 break;
b69ab3149 case 'common':
b69ab3150 beforeClass = undefined;
b69ab3151 afterClass = undefined;
b69ab3152 break;
b69ab3153 case 'expanded':
b69ab3154 beforeClass = 'patch-expanded';
b69ab3155 afterClass = 'patch-expanded';
b69ab3156 break;
b69ab3157 }
b69ab3158
b69ab3159 // Note that 'expanded' is a special case of 'common' where it is code that is
b69ab3160 // common to both sides of the diff, but was previously displayed as
b69ab3161 // collapsed. For whatever reason, GitHub does not make it possible to comment
b69ab3162 // on lines outside of the patch contents in PRs:
b69ab3163 //
b69ab3164 // https://github.com/isaacs/github/issues/1655
b69ab3165 //
b69ab3166 // Even if you try to do so programmatically via the GraphQL API, it *still*
b69ab3167 // doesn't work, so this seems to be some quirk in the underlying data model.
b69ab3168 const canComment = rowType !== 'expanded';
b69ab3169
b69ab3170 return [
b69ab3171 LineNumber({
b69ab3172 className: beforeClass,
b69ab3173 lineNumber: beforeLineNumber,
b69ab3174 path,
b69ab3175 side: 'LEFT',
b69ab3176 column: 0,
b69ab3177 canComment,
b69ab3178 }),
b69ab3179 <td data-column={unified ? 2 : 1} className={beforeClass}>
b69ab3180 {before}
b69ab3181 </td>,
b69ab3182 LineNumber({
b69ab3183 className: afterClass,
b69ab3184 lineNumber: afterLineNumber,
b69ab3185 path,
b69ab3186 side: 'RIGHT',
b69ab3187 column: unified ? 1 : 2,
b69ab3188 canComment,
b69ab3189 openFileToLine, // opening to a line number only makes sense on the "right" comparison side
b69ab3190 }),
b69ab3191 <td data-column={unified ? 2 : 3} className={afterClass}>
b69ab3192 {after}
b69ab3193 </td>,
b69ab3194 ];
b69ab3195}
b69ab3196
b69ab3197type LineNumberProps = {
b69ab3198 className?: string;
b69ab3199 lineNumber: number | null;
b69ab31100 path: string;
b69ab31101 side: 'LEFT' | 'RIGHT';
b69ab31102 column: number;
b69ab31103 canComment: boolean;
b69ab31104 openFileToLine?: (lineNumber: OneIndexedLineNumber) => unknown;
b69ab31105};
b69ab31106
b69ab31107function LineNumber({
b69ab31108 className,
b69ab31109 lineNumber,
b69ab31110 path,
b69ab31111 side,
b69ab31112 column,
b69ab31113 openFileToLine,
b69ab31114}: LineNumberProps): JSX.Element {
b69ab31115 const clickableLineNumber = openFileToLine != null && lineNumber != null;
b69ab31116 const extraClassName =
b69ab31117 (className != null ? ` ${className}-number` : '') + (clickableLineNumber ? ' clickable' : '');
b69ab31118 return (
b69ab31119 <td
b69ab31120 className={`lineNumber${extraClassName} lineNumber-${side}`}
b69ab31121 data-line-number={lineNumber}
b69ab31122 data-path={path}
b69ab31123 data-side={side}
b69ab31124 data-column={column}
b69ab31125 onClick={clickableLineNumber ? () => openFileToLine(lineNumber) : undefined}>
b69ab31126 {lineNumber}
b69ab31127 </td>
b69ab31128 );
b69ab31129}
b69ab31130
b69ab31131export function BlankLineNumber({before}: ExclusiveOr<{before: true}, {after: true}>) {
b69ab31132 return (
b69ab31133 <td
b69ab31134 className={
b69ab31135 before
b69ab31136 ? 'patch-remove-line-number lineNumber lineNumber-LEFT'
b69ab31137 : 'patch-add-line-number lineNumber lineNumber-RIGHT'
b69ab31138 }
b69ab31139 />
b69ab31140 );
b69ab31141}