github.com/treeverse/lakefs@v1.24.1-0.20240520134607-95648127bfb0/webui/src/pages/repositories/repository/commits/index.jsx (about)

     1  import React, {useEffect, useState} from "react";
     2  import { useOutletContext } from "react-router-dom";
     3  import dayjs from "dayjs";
     4  import {BrowserIcon, LinkIcon, PackageIcon, PlayIcon} from "@primer/octicons-react";
     5  
     6  import {commits} from "../../../../lib/api";
     7  import ButtonGroup from "react-bootstrap/ButtonGroup";
     8  import Card from "react-bootstrap/Card";
     9  import ListGroup from "react-bootstrap/ListGroup";
    10  
    11  import {
    12      ActionGroup,
    13      ActionsBar,
    14      ClipboardButton,
    15      AlertError,
    16      LinkButton,
    17      Loading, RefreshButton
    18  } from "../../../../lib/components/controls";
    19  import {CommitMessage} from "../../../../lib/components/repository/commits";
    20  import {useRefs} from "../../../../lib/hooks/repo";
    21  import {useAPIWithPagination} from "../../../../lib/hooks/api";
    22  import {Paginator} from "../../../../lib/components/pagination";
    23  import RefDropdown from "../../../../lib/components/repository/refDropdown";
    24  import {Link} from "../../../../lib/components/nav";
    25  import {useRouter} from "../../../../lib/hooks/router";
    26  import {RepoError} from "../error";
    27  
    28  
    29  const CommitWidget = ({ repo, commit }) => {
    30  
    31      const buttonVariant = "outline-dark";
    32  
    33      return (
    34          <ListGroup.Item>
    35              <div className="clearfix">
    36                  <div className="float-start">
    37                      <h6>
    38                          <Link href={{
    39                              pathname: '/repositories/:repoId/commits/:commitId',
    40                              params: {repoId: repo.id, commitId: commit.id}
    41                          }}>
    42                              <CommitMessage commit={commit}/>
    43                          </Link>
    44                      </h6>
    45                      <p>
    46                          <small>
    47                              <strong>{commit.committer}</strong> committed at <strong>{dayjs.unix(commit.creation_date).format("MM/DD/YYYY HH:mm:ss")}</strong> ({dayjs.unix(commit.creation_date).fromNow()})
    48                          </small>
    49                      </p>
    50                  </div>
    51                  <div className="float-end">
    52                      <ButtonGroup className="commit-actions">
    53                          <LinkButton
    54                              buttonVariant="outline-dark"
    55                              href={{
    56                                  pathname: '/repositories/:repoId/commits/:commitId',
    57                                  params: {repoId: repo.id, commitId: commit.id}
    58                              }}>
    59                              <code>{commit.id.substr(0, 16)}</code>
    60                          </LinkButton>
    61                          <LinkButton
    62                              buttonVariant={buttonVariant}
    63                              href={{pathname: '/repositories/:repoId/actions', query: {commit: commit.id}, params: {repoId: repo.id}}}
    64                              tooltip="View Commit Action runs">
    65                              <PlayIcon/>
    66                          </LinkButton>
    67                          <ClipboardButton variant={buttonVariant} text={commit.id} tooltip="Copy ID to clipboard"/>
    68                          <ClipboardButton variant={buttonVariant} text={`lakefs://${repo.id}/${commit.id}`} tooltip="Copy URI to clipboard" icon={<LinkIcon/>}/>
    69                          <ClipboardButton variant={buttonVariant} text={`s3://${repo.id}/${commit.id}`} tooltip="Copy S3 URI to clipboard" icon={<PackageIcon/>}/>
    70                          <LinkButton
    71                              buttonVariant="outline-dark"
    72                              href={{pathname: '/repositories/:repoId/objects', params: {repoId: repo.id}, query: {ref: commit.id}}}
    73                              tooltip="Browse objects at this commit">
    74                              <BrowserIcon/>
    75                          </LinkButton>
    76  
    77                      </ButtonGroup>
    78                  </div>
    79              </div>
    80          </ListGroup.Item>
    81      );
    82  }
    83  
    84  
    85  const CommitsBrowser = ({ repo, reference, after, onPaginate, onSelectRef }) => {
    86  
    87      const [refresh, setRefresh] = useState(true)
    88      const { results, error, loading, nextPage } = useAPIWithPagination(async () => {
    89          return commits.log(repo.id, reference.id, after)
    90      }, [repo.id, reference.id, refresh, after])
    91  
    92      if (loading) return <Loading/>
    93      if (error) return <AlertError error={error}/>
    94  
    95      return (
    96          <div className="mb-5">
    97  
    98              <ActionsBar>
    99                  <ActionGroup orientation="left">
   100                      <RefDropdown
   101                          repo={repo}
   102                          selected={(reference) ? reference : null}
   103                          withCommits={true}
   104                          withWorkspace={false}
   105                          selectRef={onSelectRef}
   106                      />
   107                  </ActionGroup>
   108  
   109                  <ActionGroup orientation="right">
   110                      <RefreshButton onClick={() => { setRefresh(!refresh); }}/>
   111                  </ActionGroup>
   112              </ActionsBar>
   113  
   114              <Card>
   115                  <ListGroup variant="flush">
   116                  {results.map(commit => (
   117                      <CommitWidget key={commit.id} repo={repo} commit={commit}/>
   118                  ))}
   119                  </ListGroup>
   120              </Card>
   121              <Paginator onPaginate={onPaginate} nextPage={nextPage} after={after}/>
   122          </div>
   123      )
   124  
   125  
   126  }
   127  
   128  
   129  const CommitsContainer = () => {
   130      const router = useRouter();
   131      const { after } = router.query;
   132      const { repo, reference, loading ,error } = useRefs();
   133  
   134      if (loading) return <Loading/>;
   135      if (error) return <RepoError error={error}/>;
   136  
   137      const params = {repoId: repo.id};
   138  
   139      return (
   140          <CommitsBrowser
   141              repo={repo}
   142              reference={reference}
   143              onSelectRef={ref => router.push({
   144                  pathname: `/repositories/:repoId/commits`,
   145                  query: {ref: ref.id},
   146                  params
   147              })}
   148              after={(after) ? after : ""}
   149              onPaginate={after => router.push({
   150                      pathname: `/repositories/:repoId/commits`,
   151                      query: {ref: reference.id, after},
   152                      params
   153                  })}
   154          />
   155      );
   156  };
   157  
   158  
   159  const RepositoryCommitsPage = () => {
   160    const [setActivePage] = useOutletContext();
   161    useEffect(() => setActivePage('commits'), [setActivePage]);
   162    return <CommitsContainer />;
   163  };
   164  
   165  export default RepositoryCommitsPage;