import {Fragment} from 'react'; import styled from '@emotion/styled'; import {deleteMonitor} from 'sentry/actionCreators/monitors'; import {openConfirmModal} from 'sentry/components/confirm'; import {DropdownMenu, MenuItemProps} from 'sentry/components/dropdownMenu'; import IdBadge from 'sentry/components/idBadge'; import Link from 'sentry/components/links/link'; import List from 'sentry/components/list'; import ListItem from 'sentry/components/list/listItem'; import Text from 'sentry/components/text'; import TextOverflow from 'sentry/components/textOverflow'; import TimeSince from 'sentry/components/timeSince'; import {IconEllipsis} from 'sentry/icons'; import {t, tct} from 'sentry/locale'; import {space} from 'sentry/styles/space'; import {Organization} from 'sentry/types'; import useApi from 'sentry/utils/useApi'; import {normalizeUrl} from 'sentry/utils/withDomainRequired'; import {scheduleAsText} from 'sentry/views/monitors/utils'; import {Monitor, MonitorEnvironment, MonitorStatus} from '../types'; import {MonitorBadge} from './monitorBadge'; interface MonitorRowProps { monitor: Monitor; onDelete: () => void; organization: Organization; monitorEnv?: MonitorEnvironment; } function MonitorRow({monitor, monitorEnv, organization, onDelete}: MonitorRowProps) { const api = useApi(); const lastCheckin = monitorEnv?.lastCheckIn ? ( ) : null; const deletionModalMessage = ( {tct('Are you sure you want to permanently delete "[name]"?', { name: monitor.name, })} {monitor.environments.length > 1 && ( {t( `This will delete check-in data for this monitor associated with these environments:` )} {monitor.environments.map(environment => ( {environment.name} ))} )} ); const actions: MenuItemProps[] = [ { key: 'edit', label: t('Edit'), // TODO(davidenwang): Right now we have to pass the environment // through the URL so that when we save the monitor and are // redirected back to the details page it queries the backend // for a monitor environment with check-in data to: normalizeUrl({ pathname: `/organizations/${organization.slug}/crons/${monitor.slug}/edit/`, query: {environment: monitorEnv?.name}, }), }, { key: 'delete', label: t('Delete'), priority: 'danger', onAction: () => { openConfirmModal({ onConfirm: async () => { await deleteMonitor(api, organization.slug, monitor.slug); onDelete(); }, header: t('Delete Monitor?'), message: deletionModalMessage, confirmText: t('Delete Monitor'), priority: 'danger', }); }, }, ]; const monitorDetailUrl = `/organizations/${organization.slug}/crons/${monitor.slug}/${ monitorEnv ? `?environment=${monitorEnv.name}` : '' }`; // TODO(davidenwang): Change accordingly when we have ObjectStatus on monitor const monitorStatus = monitor.status !== 'disabled' && monitorEnv ? monitorEnv.status : monitor.status; return ( {monitor.name} {monitor.slug} {monitorStatus === MonitorStatus.DISABLED ? t('Paused') : monitorStatus === MonitorStatus.ACTIVE || !lastCheckin ? t('Waiting for first check-in') : monitorStatus === MonitorStatus.OK ? tct('Check-in [lastCheckin]', {lastCheckin}) : monitorStatus === MonitorStatus.MISSED_CHECKIN ? tct('Missed [lastCheckin]', {lastCheckin}) : monitorStatus === MonitorStatus.ERROR ? tct('Failed [lastCheckin]', {lastCheckin}) : monitorStatus === MonitorStatus.TIMEOUT ? t('Timed out') : null} {scheduleAsText(monitor.config)} {monitorEnv?.nextCheckIn && monitorEnv.status !== MonitorStatus.DISABLED && monitorEnv.status !== MonitorStatus.ACTIVE ? ( ) : ( '\u2014' )} {monitorEnv?.name ?? '\u2014'} , showChevron: false, }} /> ); } export {MonitorRow}; const MonitorName = styled('div')` display: flex; align-items: center; gap: ${space(2)}; font-size: ${p => p.theme.fontSizeLarge}; `; const NameAndSlug = styled('div')` display: flex; flex-direction: column; gap: ${space(0.25)}; `; const MonitorSlug = styled('div')` font-size: ${p => p.theme.fontSizeSmall}; color: ${p => p.theme.subText}; `; const MonitorColumn = styled('div')` display: flex; align-items: center; `; const ActionsColumn = styled('div')` display: flex; align-items: center; justify-content: center; `; const AdditionalEnvironmentWarning = styled('div')` margin: ${space(1)} 0; `;