import styled from '@emotion/styled'; import startCase from 'lodash/startCase'; import Alert from 'app/components/alert'; import Button from 'app/components/button'; import Link from 'app/components/links/link'; import {PanelItem} from 'app/components/panels'; import {IconWarning} from 'app/icons'; import {t} from 'app/locale'; import PluginIcon from 'app/plugins/components/pluginIcon'; import space from 'app/styles/space'; import {IntegrationInstallationStatus, Organization, SentryApp} from 'app/types'; import { convertIntegrationTypeToSnakeCase, trackIntegrationEvent, } from 'app/utils/integrationUtil'; import IntegrationStatus from './integrationStatus'; type Props = { organization: Organization; type: 'plugin' | 'firstParty' | 'sentryApp' | 'documentIntegration'; slug: string; displayName: string; status?: IntegrationInstallationStatus; publishStatus: 'unpublished' | 'published' | 'internal'; configurations: number; categories: string[]; alertText?: string; }; const urlMap = { plugin: 'plugins', firstParty: 'integrations', sentryApp: 'sentry-apps', documentIntegration: 'document-integrations', }; const IntegrationRow = (props: Props) => { const { organization, type, slug, displayName, status, publishStatus, configurations, categories, alertText, } = props; const baseUrl = publishStatus === 'internal' ? `/settings/${organization.slug}/developer-settings/${slug}/` : `/settings/${organization.slug}/${urlMap[type]}/${slug}/`; const renderDetails = () => { if (type === 'sentryApp') { return publishStatus !== 'published' && ; } // TODO: Use proper translations return configurations > 0 ? ( {`${configurations} Configuration${ configurations > 1 ? 's' : '' }`} ) : null; }; const renderStatus = () => { // status should be undefined for document integrations if (status) { return ; } return {t('Learn More')}; }; return ( {displayName} {renderStatus()} {renderDetails()} {categories?.map(category => ( ))} {alertText && ( }> {alertText} trackIntegrationEvent( 'integrations.resolve_now_clicked', { integration_type: convertIntegrationTypeToSnakeCase(type), integration: slug, }, organization ) } > {t('Resolve Now')} )} ); }; const PanelRow = styled(PanelItem)` flex-direction: column; `; const FlexContainer = styled('div')` display: flex; align-items: center; padding: ${space(2)}; `; const InternalContainer = styled(FlexContainer)` padding: 0 ${space(2)}; `; const Container = styled('div')` flex: 1; padding: 0 16px; `; const IntegrationName = styled(Link)` font-weight: bold; `; const IntegrationDetails = styled('div')` display: flex; align-items: center; margin-top: 6px; font-size: 0.8em; `; const StyledLink = styled(Link)` color: ${p => p.theme.gray300}; &:before { content: '|'; color: ${p => p.theme.gray200}; margin-right: ${space(0.75)}; font-weight: normal; } `; const LearnMore = styled(Link)` color: ${p => p.theme.gray300}; `; type PublishStatusProps = {status: SentryApp['status']; theme?: any}; const PublishStatus = styled(({status, ...props}: PublishStatusProps) => (
{t(`${status}`)}
))` color: ${(props: PublishStatusProps) => props.status === 'published' ? props.theme.success : props.theme.gray300}; font-weight: light; margin-right: ${space(0.75)}; text-transform: capitalize; &:before { content: '|'; color: ${p => p.theme.gray200}; margin-right: ${space(0.75)}; font-weight: normal; } `; // TODO(Priscila): Replace this component with the Tag component const CategoryTag = styled( ({ priority: _priority, category, ...p }: { category: string; priority: boolean; theme?: any; }) =>
{category}
)` display: flex; flex-direction: row; padding: 1px 10px; background: ${p => (p.priority ? p.theme.purple200 : p.theme.gray100)}; border-radius: 20px; font-size: ${space(1.5)}; margin-right: ${space(1)}; line-height: ${space(3)}; text-align: center; color: ${p => (p.priority ? p.theme.white : p.theme.gray500)}; `; const ResolveNowButton = styled(Button)` color: ${p => p.theme.subText}; float: right; `; const AlertContainer = styled('div')` padding: 0px ${space(3)} 0px 68px; `; export default IntegrationRow;