commitLink.tsx 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. import * as React from 'react';
  2. import Button from 'app/components/button';
  3. import ExternalLink from 'app/components/links/externalLink';
  4. import {IconBitbucket, IconGithub, IconGitlab, IconVsts} from 'app/icons';
  5. import {t} from 'app/locale';
  6. import {Repository} from 'app/types';
  7. import {getShortCommitHash} from 'app/utils';
  8. type CommitFormatterParameters = {
  9. baseUrl: string;
  10. commitId: string;
  11. };
  12. type CommitProvider = {
  13. icon: React.ReactNode;
  14. providerIds: string[];
  15. commitUrl: (CommitFormatterParameters) => string;
  16. };
  17. // TODO(epurkhiser, jess): This should be moved into plugins.
  18. const SUPPORTED_PROVIDERS: Readonly<CommitProvider[]> = [
  19. {
  20. icon: <IconGithub size="xs" />,
  21. providerIds: ['github', 'integrations:github', 'integrations:github_enterprise'],
  22. commitUrl: ({baseUrl, commitId}) => `${baseUrl}/commit/${commitId}`,
  23. },
  24. {
  25. icon: <IconBitbucket size="xs" />,
  26. providerIds: ['bitbucket', 'integrations:bitbucket'],
  27. commitUrl: ({baseUrl, commitId}) => `${baseUrl}/commits/${commitId}`,
  28. },
  29. {
  30. icon: <IconVsts size="xs" />,
  31. providerIds: ['visualstudio', 'integrations:vsts'],
  32. commitUrl: ({baseUrl, commitId}) => `${baseUrl}/commit/${commitId}`,
  33. },
  34. {
  35. icon: <IconGitlab size="xs" />,
  36. providerIds: ['gitlab', 'integrations:gitlab'],
  37. commitUrl: ({baseUrl, commitId}) => `${baseUrl}/commit/${commitId}`,
  38. },
  39. ];
  40. type Props = {
  41. commitId: string;
  42. repository?: Repository;
  43. inline?: boolean;
  44. };
  45. function CommitLink({inline, commitId, repository}: 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 external href={commitUrl} size="small" icon={providerData.icon}>
  67. {shortId}
  68. </Button>
  69. ) : (
  70. <ExternalLink className="inline-commit" href={commitUrl}>
  71. {providerData.icon}
  72. {' ' + shortId}
  73. </ExternalLink>
  74. );
  75. }
  76. export default CommitLink;