GitFOSS
.ts
TypeScript
(application/typescript)
// 1st-party
import type { ReactIsland } from "@ethicdevs/react-monolith";
// 3rd-party
import React, { useCallback } from "react";
import styled from "styled-components";
// app
import { RepositoryFile, RepositoryLog } from "../types";

export interface RepositoryTreeViewProps {
  currPath: string;
  lastCommit: RepositoryLog;
  orgSlug: string;
  repoFiles: RepositoryFile[];
  repoSlug: string;
}

const RepositoryTreeView: ReactIsland<RepositoryTreeViewProps> = ({
  currPath,
  lastCommit,
  orgSlug,
  repoFiles,
  repoSlug,
}) => {
  const buildRepoFileLink = useCallback(
    (file: RepositoryFile) => {
      const fileName = `${file.name}${file.type === "tree" ? "/" : ""}`;
      return {
        text: fileName,
        href:
          currPath === "/"
            ? `/${orgSlug}/${repoSlug}/main/tree/${fileName}`
            : `/${orgSlug}/${repoSlug}/main/tree/${
                currPath.endsWith("/") ? currPath : `${currPath}/`
              }${fileName}`,
      };
    },
    [orgSlug, repoSlug, currPath]
  );

  const currPathParts = currPath.split("/");

  let prevPath: string | null = currPathParts
    .slice(0, currPathParts.length - 2)
    .join("/");
  prevPath = prevPath.trim() === "" ? null : prevPath;
  prevPath = prevPath == null ? "/" : prevPath;

  const prevPathLink =
    prevPath === "/"
      ? `/${orgSlug}/${repoSlug}`
      : `/${orgSlug}/${repoSlug}/main/tree/${
          prevPath.endsWith("/") ? prevPath : `${prevPath}/`
        }`;
  const shouldShowPrevPath = currPath !== "/";

  return (
    <StyledRepositoryTreeViewContainer>
      <div>
        <strong>{lastCommit.author.name}</strong>
        {" ∙ "}
        <span>{lastCommit.subject}</span>
        {" - "}
        <span>
          {lastCommit.abbreviated_commit}
          {lastCommit.abbreviated_parent.trim() != ""
            ? ` ∙ parent ${lastCommit.abbreviated_parent}`
            : ""}
        </span>
        {" ∙ "}
        <span>{new Date(lastCommit.author.date).toUTCString()}</span>
        <a href={`/${orgSlug}/${repoSlug}/commits`}>History</a>
      </div>
      <div>
        <ul>
          {shouldShowPrevPath && (
            <li key={"go-previous"}>
              <a href={prevPathLink}>..</a>
            </li>
          )}
          {repoFiles.map((file) => {
            const fileLink = buildRepoFileLink(file);
            return (
              <li key={file.id}>
                <a href={fileLink.href}>{fileLink.text}</a>
              </li>
            );
          })}
        </ul>
      </div>
    </StyledRepositoryTreeViewContainer>
  );
};

const StyledRepositoryTreeViewContainer = styled.div`
  width: 100%;
`;

RepositoryTreeView.displayName = "RepositoryTreeView";
export default RepositoryTreeView;