commitLink.tsx 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  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. repository?: Repository;
  43. showIcon?: boolean;
  44. };
  45. function CommitLink({inline, commitId, repository, showIcon = true}: Props) {
  46. if (!commitId || !repository) {
  47. return <span>{t('Unknown Commit')}</span>;
  48. }
  49. const shortId = getShortCommitHash(commitId);
  50. const providerData = SUPPORTED_PROVIDERS.find(provider => {
  51. if (!repository.provider) {
  52. return false;
  53. }
  54. return provider.providerIds.includes(repository.provider.id);
  55. });
  56. if (providerData === undefined) {
  57. return <span>{shortId}</span>;
  58. }
  59. const commitUrl =
  60. repository.url &&
  61. providerData.commitUrl({
  62. commitId,
  63. baseUrl: repository.url,
  64. });
  65. return !inline ? (
  66. <Button
  67. external
  68. href={commitUrl}
  69. size="sm"
  70. icon={showIcon ? providerData.icon : null}
  71. >
  72. {shortId}
  73. </Button>
  74. ) : (
  75. <ExternalLink href={commitUrl}>
  76. {showIcon ? providerData.icon : null}
  77. {' ' + shortId}
  78. </ExternalLink>
  79. );
  80. }
  81. export default CommitLink;