GitFOSS
.ts
TypeScript
(application/typescript)
// 1st-party
import type { ReactIsland } from "@ethicdevs/react-monolith";
// 3rd-party
import React from "react";
// app
import type {
  RepositoryFileDiff,
  RepositoryFileDiffChunk,
  WithThemeSchemeProp,
} from "../types";
import { Code, Card, Grid, getThemedCodeCss } from "../components";

export interface RepositoryFilesDiffsList {
  filesDiffs: RepositoryFileDiff[];
  orgSlug: string;
  repoSlug: string;
  commitHash: string;
}

const getChunkContent = (chunk: RepositoryFileDiffChunk): string => {
  let sb = [] as string[];
  sb.push(chunk.content);
  chunk.changes.forEach((change) => sb.push(change.content));
  return `${sb.join("\n")}\n`;
};

const RepositoryFilesDiffsList: ReactIsland<
  RepositoryFilesDiffsList & WithThemeSchemeProp
> = ({ commitHash, filesDiffs, orgSlug, repoSlug, themeScheme }) => (
  <>
    {getThemedCodeCss(themeScheme)}
    <Grid.Col fluid>
      {filesDiffs.map(({ chunks, ...diff }, idx) => (
        <Card
          key={[diff.from, diff.to].join(":")}
          style={{ marginTop: idx > 0 ? 16 : 0, width: "100%" }}
          themeScheme={themeScheme}
        >
          <Grid.Col fluid nowrap>
            <Grid.Row fluid nowrap>
              <strong>{diff.from}</strong>
              <span style={{ marginLeft: 16 }}>{" -> "}</span>
              <strong style={{ marginLeft: 16 }}>{diff.to}</strong>
            </Grid.Row>
            <Grid.Row
              fluid
              nowrap
              alignItems={"center"}
              style={{ marginTop: 8 }}
            >
              <div>
                <strong>additions:</strong> <span>{diff.additions}</span>
              </div>
              <div style={{ marginLeft: 16 }}>
                <strong>deletions:</strong> <span>{diff.deletions}</span>
              </div>
              <div style={{ marginLeft: 16 }}>
                <a
                  href={`/${orgSlug}/${repoSlug}/${commitHash}/tree/${diff.to}`}
                >
                  View file (current ref)
                </a>
                <a
                  href={`/${orgSlug}/${repoSlug}/main/tree/${diff.to}`}
                  style={{ marginLeft: 16 }}
                >
                  View file (main)
                </a>
              </div>
            </Grid.Row>
          </Grid.Col>
          <Grid.Col fluid style={{ marginTop: 8 }}>
            {chunks.map((chunk, idx) => (
              <Code
                key={[idx, chunk.content].join(":")}
                code={getChunkContent(chunk)}
                language={"diff"}
                themeScheme={themeScheme}
              />
            ))}
          </Grid.Col>
        </Card>
      ))}
    </Grid.Col>
  </>
);

RepositoryFilesDiffsList.displayName = "RepositoryFilesDiffsList";
export default RepositoryFilesDiffsList;