import {Fragment} from 'react'; import styled from '@emotion/styled'; import { cancelDeleteRepository, deleteRepository, } from 'sentry/actionCreators/integrations'; import {openModal} from 'sentry/actionCreators/modal'; import {Client} from 'sentry/api'; import Access from 'sentry/components/acl/access'; import Button from 'sentry/components/button'; import Confirm from 'sentry/components/confirm'; import ExternalLink from 'sentry/components/links/externalLink'; import {PanelItem} from 'sentry/components/panels'; import RepositoryEditForm from 'sentry/components/repositoryEditForm'; import Tooltip from 'sentry/components/tooltip'; import {IconDelete, IconEdit} from 'sentry/icons'; import {t} from 'sentry/locale'; import space from 'sentry/styles/space'; import {Organization, Repository, RepositoryStatus} from 'sentry/types'; import withOrganization from 'sentry/utils/withOrganization'; type Props = { api: Client; orgId: string; organization: Organization; repository: Repository; onRepositoryChange?: (data: {id: string; status: RepositoryStatus}) => void; showProvider?: boolean; }; function getStatusLabel(repo: Repository) { switch (repo.status) { case RepositoryStatus.PENDING_DELETION: return 'Deletion Queued'; case RepositoryStatus.DELETION_IN_PROGRESS: return 'Deletion in Progress'; case RepositoryStatus.DISABLED: return 'Disabled'; case RepositoryStatus.HIDDEN: return 'Disabled'; default: return null; } } function RepositoryRow({ api, repository, onRepositoryChange, organization, orgId, showProvider = false, }: Props) { const isCustomRepo = organization.features.includes('integrations-custom-scm') && repository.provider.id === 'integrations:custom_scm'; const isActive = repository.status === RepositoryStatus.ACTIVE; const cancelDelete = () => cancelDeleteRepository(api, orgId, repository.id).then( data => { if (onRepositoryChange) { onRepositoryChange(data); } }, () => {} ); const deleteRepo = () => deleteRepository(api, orgId, repository.id).then( data => { if (onRepositoryChange) { onRepositoryChange(data); } }, () => {} ); const handleEditRepo = (data: Repository) => { onRepositoryChange?.(data); }; const renderDeleteButton = (hasAccess: boolean) => ( } aria-label={t('delete')} disabled={!hasAccess} /> ); const triggerModal = () => openModal(({Body, Header, closeModal}) => (
{t('Edit Repository')}
)); return ( {({hasAccess}) => ( {repository.name} {!isActive && — {getStatusLabel(repository)}} {repository.status === RepositoryStatus.PENDING_DELETION && ( {t('Cancel')} )}
{showProvider && {repository.provider.name}} {showProvider && repository.url &&  — } {repository.url && ( {repository.url.replace('https://', '')} )}
{isCustomRepo ? ( } aria-label={t('edit')} disabled={ !hasAccess || (!isActive && repository.status !== RepositoryStatus.DISABLED) } onClick={triggerModal} /> {renderDeleteButton(hasAccess)} ) : ( renderDeleteButton(hasAccess) )}
)}
); } const StyledPanelItem = styled(PanelItem)<{status: RepositoryStatus}>` /* shorter top padding because of title lineheight */ padding: ${space(1)} ${space(2)} ${space(2)}; justify-content: space-between; align-items: center; flex: 1; ${p => p.status === RepositoryStatus.DISABLED && ` filter: grayscale(1); opacity: 0.4; `}; &:last-child { border-bottom: none; } `; const StyledButton = styled(Button)` margin-left: ${space(1)}; `; const RepositoryTitleAndUrl = styled('div')` display: flex; flex-direction: column; `; const EditAndDelete = styled('div')` display: flex; margin-left: ${space(1)}; `; const RepositoryTitle = styled('div')` /* accommodate cancel button height */ line-height: 26px; `; export default withOrganization(RepositoryRow);