commitLink.tsx 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. import Button from 'sentry/components/button';
  2. import ExternalLink from 'sentry/components/links/externalLink';
  3. import {IconBitbucket, IconGithub, IconGitlab, IconVsts} from 'sentry/icons';
  4. import {t} from 'sentry/locale';
  5. import {Repository} from 'sentry/types';
  6. import {getShortCommitHash} from 'sentry/utils';
  7. type CommitFormatterParameters = {
  8. baseUrl: string;
  9. commitId: string;
  10. };
  11. type CommitProvider = {
  12. commitUrl: (opts: CommitFormatterParameters) => string;
  13. icon: React.ReactNode;
  14. providerIds: string[];
  15. };
  16. // TODO(epurkhiser, jess): This should be moved into plugins.
  17. const SUPPORTED_PROVIDERS: Readonly<CommitProvider[]> = [
  18. {
  19. icon: <IconGithub size="xs" />,
  20. providerIds: ['github', 'integrations:github', 'integrations:github_enterprise'],
  21. commitUrl: ({baseUrl, commitId}) => `${baseUrl}/commit/${commitId}`,
  22. },
  23. {
  24. icon: <IconBitbucket size="xs" />,
  25. providerIds: ['bitbucket', 'integrations:bitbucket'],
  26. commitUrl: ({baseUrl, commitId}) => `${baseUrl}/commits/${commitId}`,
  27. },
  28. {
  29. icon: <IconVsts size="xs" />,
  30. providerIds: ['visualstudio', 'integrations:vsts'],
  31. commitUrl: ({baseUrl, commitId}) => `${baseUrl}/commit/${commitId}`,
  32. },
  33. {
  34. icon: <IconGitlab size="xs" />,
  35. providerIds: ['gitlab', 'integrations:gitlab'],
  36. commitUrl: ({baseUrl, commitId}) => `${baseUrl}/commit/${commitId}`,
  37. },
  38. ];
  39. type Props = {
  40. commitId?: string;
  41. inline?: boolean;
  42. onClick?: () => void;
  43. repository?: Repository;
  44. showIcon?: boolean;
  45. };
  46. function CommitLink({inline, commitId, repository, showIcon = true, onClick}: Props) {
  47. if (!commitId || !repository) {
  48. return <span>{t('Unknown Commit')}</span>;
  49. }
  50. const shortId = getShortCommitHash(commitId);
  51. const providerData = SUPPORTED_PROVIDERS.find(provider => {
  52. if (!repository.provider) {
  53. return false;
  54. }
  55. return provider.providerIds.includes(repository.provider.id);
  56. });
  57. if (providerData === undefined) {
  58. return <span>{shortId}</span>;
  59. }
  60. const commitUrl =
  61. repository.url &&
  62. providerData.commitUrl({
  63. commitId,
  64. baseUrl: repository.url,
  65. });
  66. return !inline ? (
  67. <Button
  68. external
  69. href={commitUrl}
  70. size="sm"
  71. icon={showIcon ? providerData.icon : null}
  72. onClick={onClick}
  73. >
  74. {shortId}
  75. </Button>
  76. ) : (
  77. <ExternalLink href={commitUrl} onClick={onClick}>
  78. {showIcon ? providerData.icon : null}
  79. {' ' + shortId}
  80. </ExternalLink>
  81. );
  82. }
  83. export default CommitLink;