projectPluginRow.tsx 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. import {PureComponent} from 'react';
  2. import type {RouteComponentProps} from 'react-router';
  3. import {css} from '@emotion/react';
  4. import styled from '@emotion/styled';
  5. import Access from 'sentry/components/acl/access';
  6. import ExternalLink from 'sentry/components/links/externalLink';
  7. import Link from 'sentry/components/links/link';
  8. import Switch from 'sentry/components/switchButton';
  9. import {t} from 'sentry/locale';
  10. import PluginIcon from 'sentry/plugins/components/pluginIcon';
  11. import type {Plugin} from 'sentry/types/integrations';
  12. import type {Organization} from 'sentry/types/organization';
  13. import type {Project} from 'sentry/types/project';
  14. import getDynamicText from 'sentry/utils/getDynamicText';
  15. import {trackIntegrationAnalytics} from 'sentry/utils/integrationUtil';
  16. import recreateRoute from 'sentry/utils/recreateRoute';
  17. import withOrganization from 'sentry/utils/withOrganization';
  18. const grayText = css`
  19. color: #979ba0;
  20. `;
  21. type Props = {
  22. onChange: (id: string, enabled: boolean) => void;
  23. organization: Organization;
  24. project: Project;
  25. } & Plugin &
  26. Pick<RouteComponentProps<{}, {}>, 'params' | 'routes'>;
  27. class ProjectPluginRow extends PureComponent<Props> {
  28. handleChange = () => {
  29. const {onChange, id, enabled} = this.props;
  30. onChange(id, !enabled);
  31. const eventKey = !enabled ? 'integrations.enabled' : 'integrations.disabled';
  32. trackIntegrationAnalytics(eventKey, {
  33. integration: id,
  34. integration_type: 'plugin',
  35. view: 'legacy_integrations',
  36. organization: this.props.organization,
  37. });
  38. };
  39. render() {
  40. const {
  41. id,
  42. name,
  43. slug,
  44. version,
  45. author,
  46. hasConfiguration,
  47. enabled,
  48. canDisable,
  49. project,
  50. } = this.props;
  51. const configureUrl = recreateRoute(id, this.props);
  52. return (
  53. <Access access={['project:write']} project={project}>
  54. {({hasAccess}) => {
  55. const LinkOrSpan = hasAccess ? Link : 'span';
  56. return (
  57. <PluginItem key={id} className={slug}>
  58. <PluginInfo>
  59. <StyledPluginIcon size={48} pluginId={id} />
  60. <PluginDescription>
  61. <PluginName>
  62. {`${name} `}
  63. {getDynamicText({
  64. value: (
  65. <Version>{version ? `v${version}` : <em>{t('n/a')}</em>}</Version>
  66. ),
  67. fixed: <Version>v10</Version>,
  68. })}
  69. </PluginName>
  70. <div>
  71. {author && (
  72. <ExternalLink css={grayText} href={author.url}>
  73. {author.name}
  74. </ExternalLink>
  75. )}
  76. {hasConfiguration && (
  77. <span>
  78. {' '}
  79. &middot;{' '}
  80. <LinkOrSpan css={grayText} to={configureUrl}>
  81. {t('Configure plugin')}
  82. </LinkOrSpan>
  83. </span>
  84. )}
  85. </div>
  86. </PluginDescription>
  87. </PluginInfo>
  88. <Switch
  89. size="lg"
  90. isDisabled={!hasAccess || !canDisable}
  91. isActive={enabled}
  92. toggle={this.handleChange}
  93. />
  94. </PluginItem>
  95. );
  96. }}
  97. </Access>
  98. );
  99. }
  100. }
  101. export default withOrganization(ProjectPluginRow);
  102. const PluginItem = styled('div')`
  103. display: flex;
  104. flex: 1;
  105. align-items: center;
  106. `;
  107. const PluginDescription = styled('div')`
  108. display: flex;
  109. justify-content: center;
  110. flex-direction: column;
  111. `;
  112. const PluginInfo = styled('div')`
  113. display: flex;
  114. flex: 1;
  115. line-height: 24px;
  116. `;
  117. const PluginName = styled('div')`
  118. font-size: 16px;
  119. `;
  120. const StyledPluginIcon = styled(PluginIcon)`
  121. margin-right: 16px;
  122. `;
  123. // Keeping these colors the same from old integrations page
  124. const Version = styled('span')`
  125. color: #babec2;
  126. `;