commits.tsx 4.1 KB

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