repositoryProjectPathConfigRow.tsx 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. import {Fragment} from 'react';
  2. import styled from '@emotion/styled';
  3. import Access from 'sentry/components/acl/access';
  4. import {Button} from 'sentry/components/button';
  5. import Confirm from 'sentry/components/confirm';
  6. import IdBadge from 'sentry/components/idBadge';
  7. import {Tooltip} from 'sentry/components/tooltip';
  8. import {IconDelete, IconEdit} from 'sentry/icons';
  9. import {t} from 'sentry/locale';
  10. import {space} from 'sentry/styles/space';
  11. import type {RepositoryProjectPathConfig} from 'sentry/types/integrations';
  12. import type {Project} from 'sentry/types/project';
  13. type Props = {
  14. onDelete: (pathConfig: RepositoryProjectPathConfig) => void;
  15. onEdit: (pathConfig: RepositoryProjectPathConfig) => void;
  16. pathConfig: RepositoryProjectPathConfig;
  17. project: Project;
  18. };
  19. export default function RepositoryProjectPathConfigRow({
  20. pathConfig,
  21. project,
  22. onEdit,
  23. onDelete,
  24. }: Props) {
  25. return (
  26. <Fragment>
  27. <NameRepoColumn>
  28. <ProjectRepoHolder>
  29. <RepoName>{pathConfig.repoName}</RepoName>
  30. <ProjectAndBranch>
  31. <IdBadge
  32. project={project}
  33. avatarSize={14}
  34. displayName={project.slug}
  35. avatarProps={{consistentWidth: true}}
  36. />
  37. <BranchWrapper>&nbsp;|&nbsp;{pathConfig.defaultBranch}</BranchWrapper>
  38. </ProjectAndBranch>
  39. </ProjectRepoHolder>
  40. </NameRepoColumn>
  41. <OutputPathColumn>{pathConfig.sourceRoot}</OutputPathColumn>
  42. <InputPathColumn>{pathConfig.stackRoot}</InputPathColumn>
  43. <ButtonWrapper>
  44. <Button
  45. size="sm"
  46. icon={<IconEdit size="sm" />}
  47. aria-label={t('edit')}
  48. onClick={() => onEdit(pathConfig)}
  49. />
  50. <Access access={['org:integrations']}>
  51. {({hasAccess}) => (
  52. <Tooltip
  53. title={t(
  54. 'You must be an organization owner, manager or admin to remove a code mapping.'
  55. )}
  56. disabled={hasAccess}
  57. >
  58. <Confirm
  59. onConfirm={() => onDelete(pathConfig)}
  60. message={t('Are you sure you want to remove this code mapping?')}
  61. disabled={!hasAccess}
  62. >
  63. <Button
  64. size="sm"
  65. icon={<IconDelete size="sm" />}
  66. aria-label={t('delete')}
  67. disabled={!hasAccess}
  68. />
  69. </Confirm>
  70. </Tooltip>
  71. )}
  72. </Access>
  73. </ButtonWrapper>
  74. </Fragment>
  75. );
  76. }
  77. const ProjectRepoHolder = styled('div')`
  78. display: flex;
  79. flex-direction: column;
  80. `;
  81. const RepoName = styled(`span`)`
  82. padding-bottom: ${space(1)};
  83. `;
  84. const ProjectAndBranch = styled('div')`
  85. display: flex;
  86. flex-direction: row;
  87. color: ${p => p.theme.gray300};
  88. `;
  89. // match the line height of the badge
  90. const BranchWrapper = styled('div')`
  91. line-height: 1.2;
  92. `;
  93. // Columns below
  94. const Column = styled('span')`
  95. overflow: hidden;
  96. overflow-wrap: break-word;
  97. `;
  98. export const NameRepoColumn = styled(Column)`
  99. grid-area: name-repo;
  100. `;
  101. export const OutputPathColumn = styled(Column)`
  102. grid-area: output-path;
  103. `;
  104. export const InputPathColumn = styled(Column)`
  105. grid-area: input-path;
  106. `;
  107. export const ButtonWrapper = styled(Column)`
  108. display: flex;
  109. gap: ${space(1)};
  110. `;