commitLink.tsx 2.3 KB

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