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 { Const } from "../const";
import { Card } from "../components/Card.styled";
import { Grid } from "../components/Grid";
// app islands
import Code, { getThemedCodeCss } from "../islands/Code";

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 }) => {
  let codeCounter = 0;
  return (
    <>
      {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}/${Const.PRIMARY_BRANCH_REF}/tree/${diff.to}`}
                    style={{ marginLeft: 16 }}
                  >
                    View file (${Const.PRIMARY_BRANCH_REF})
                  </a>
                </div>
              </Grid.Row>
            </Grid.Col>
            <Grid.Col fluid style={{ marginTop: 8 }}>
              {chunks.map((chunk, subIdx) => (
                <div
                  data-islandid={`${Code.name}$$${codeCounter++}`}
                  key={[idx, subIdx, chunk.content].join(":")}
                  style={{ width: "100%" }}
                >
                  <Code
                    code={getChunkContent(chunk)}
                    language={"diff"}
                    themeScheme={themeScheme}
                  />
                </div>
              ))}
            </Grid.Col>
          </Card>
        ))}
      </Grid.Col>
    </>
  );
};

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