commits.tsx 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. import {Fragment} from 'react';
  2. import type {RouteComponentProps} from 'react-router';
  3. import type {Location} from 'history';
  4. import {CommitRow} from 'sentry/components/commitRow';
  5. import * as Layout from 'sentry/components/layouts/thirds';
  6. import LoadingError from 'sentry/components/loadingError';
  7. import LoadingIndicator from 'sentry/components/loadingIndicator';
  8. import Pagination from 'sentry/components/pagination';
  9. import Panel from 'sentry/components/panels/panel';
  10. import PanelBody from 'sentry/components/panels/panelBody';
  11. import PanelHeader from 'sentry/components/panels/panelHeader';
  12. import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle';
  13. import {t} from 'sentry/locale';
  14. import type {Commit, Project, Repository} from 'sentry/types';
  15. import {formatVersion} from 'sentry/utils/formatters';
  16. import {useApiQuery} from 'sentry/utils/queryClient';
  17. import routeTitleGen from 'sentry/utils/routeTitle';
  18. import {useLocation} from 'sentry/utils/useLocation';
  19. import useOrganization from 'sentry/utils/useOrganization';
  20. import {useParams} from 'sentry/utils/useParams';
  21. import {getCommitsByRepository, getQuery, getReposToRender} from '../utils';
  22. import EmptyState from './emptyState';
  23. import RepositorySwitcher from './repositorySwitcher';
  24. import withReleaseRepos from './withReleaseRepos';
  25. interface CommitsProps extends RouteComponentProps<{release: string}, {}> {
  26. location: Location;
  27. projectSlug: Project['slug'];
  28. releaseRepos: Repository[];
  29. activeReleaseRepo?: Repository;
  30. }
  31. function Commits({activeReleaseRepo, releaseRepos, projectSlug}: CommitsProps) {
  32. const location = useLocation();
  33. const params = useParams<{release: string}>();
  34. const organization = useOrganization();
  35. const query = getQuery({location, activeRepository: activeReleaseRepo});
  36. const {
  37. data: commitList = [],
  38. isLoading: isLoadingCommitList,
  39. error: commitListError,
  40. refetch,
  41. getResponseHeader,
  42. } = useApiQuery<Commit[]>(
  43. [
  44. `/organizations/${organization.slug}/releases/${encodeURIComponent(
  45. params.release
  46. )}/commits/`,
  47. {query},
  48. ],
  49. {
  50. staleTime: Infinity,
  51. }
  52. );
  53. const commitsByRepository = getCommitsByRepository(commitList);
  54. const reposToRender = getReposToRender(Object.keys(commitsByRepository));
  55. return (
  56. <Layout.Body>
  57. <Layout.Main fullWidth>
  58. <SentryDocumentTitle
  59. title={routeTitleGen(
  60. t('Commits - Release %s', formatVersion(params.release)),
  61. organization.slug,
  62. false,
  63. projectSlug
  64. )}
  65. />
  66. {releaseRepos.length > 1 && (
  67. <RepositorySwitcher
  68. repositories={releaseRepos}
  69. activeRepository={activeReleaseRepo}
  70. />
  71. )}
  72. {commitListError && <LoadingError onRetry={refetch} />}
  73. {isLoadingCommitList ? (
  74. <LoadingIndicator />
  75. ) : commitList.length ? (
  76. <Fragment>
  77. {reposToRender.map(repoName => (
  78. <Panel key={repoName}>
  79. <PanelHeader>{repoName}</PanelHeader>
  80. <PanelBody>
  81. {commitsByRepository[repoName]?.map(commit => (
  82. <CommitRow key={commit.id} commit={commit} />
  83. ))}
  84. </PanelBody>
  85. </Panel>
  86. ))}
  87. <Pagination pageLinks={getResponseHeader?.('Link')} />
  88. </Fragment>
  89. ) : (
  90. <EmptyState>
  91. {activeReleaseRepo
  92. ? t(
  93. 'There are no commits associated with this release in the %s repository.',
  94. activeReleaseRepo.name
  95. )
  96. : t('There are no commits associated with this release.')}
  97. </EmptyState>
  98. )}
  99. </Layout.Main>
  100. </Layout.Body>
  101. );
  102. }
  103. export default withReleaseRepos(Commits);