import {useState} from 'react'; import {useTheme} from '@emotion/react'; import styled from '@emotion/styled'; import LoadingIndicator from 'sentry/components/loadingIndicator'; import {t} from 'sentry/locale'; import space from 'sentry/styles/space'; import {Organization, Project} from 'sentry/types'; import trackAdvancedAnalyticsEvent from 'sentry/utils/analytics/trackAdvancedAnalyticsEvent'; import useApi from 'sentry/utils/useApi'; import {Preset, PRESET_AGGREGATES, PresetContext} from './presets'; type Props = { organization: Organization; project: Project; className?: string; onSelect?(preset: Preset, ctx: PresetContext): void; selectedPresetId?: string; }; export default function PresetSidebar(props: Props) { return (
{t('Suggested Alerts')}
{PRESET_AGGREGATES.map((preset, i) => ( props.onSelect && props.onSelect(preset, ctx)} /> ))}
); } function PresetSidebarItem(props: { index: number; organization: Organization; preset: Preset; project: Project; onClick?: (ctx: PresetContext) => void; selected?: boolean; }) { const theme = useTheme(); const api = useApi(); const [loading, setLoading] = useState(false); const iconColor = theme.charts.getColorPalette(PRESET_AGGREGATES.length)[props.index]; return ( { if (loading) { return; } trackAdvancedAnalyticsEvent('growth.metric_alert_preset_sidebar_clicked', { organization: props.organization, preset: props.preset.id, }); setLoading(true); props.preset .makeContext(api, props.project, props.organization) .then(props.onClick) .finally(() => setLoading(false)); }} > {loading && ( )} {}

{props.preset.title}

{props.preset.description}
); } const LoadingWrapper = styled('div')` position: absolute; background-color: ${p => p.theme.overlayBackgroundAlpha}; top: 0; bottom: 0; left: 0; right: 0; display: flex; justify-content: center; align-items: center; cursor: default; `; const StyledLoadingIndicator = styled(LoadingIndicator)` margin: 0; `; const StyledPresetSidebarItemContainer = styled('div')<{selected: boolean}>` border: 1px solid transparent; position: relative; overflow: hidden; border-radius: ${p => p.theme.borderRadius}; transition: border-color 0.3s ease; padding: ${space(2)}; h1 { font-size: ${p => p.theme.fontSizeLarge}; font-weight: 500; margin-bottom: 0; color: ${p => p.theme.gray500}; } small { color: ${p => p.theme.gray300}; } display: flex; flex-direction: row; align-items: start; cursor: pointer; user-select: none; &:hover { border-color: ${p => p.theme.gray100}; } ${p => p.selected && `border-color: ${p.theme.gray200};`} `; const Header = styled('h5')` margin-left: ${space(1)}; `; const IconWrapper = styled('div')<{backgroundColor: string}>` display: flex; justify-content: center; align-items: center; padding: ${space(1)}; min-width: 40px; height: 40px; border-radius: ${p => p.theme.borderRadius}; background: ${p => p.backgroundColor}; margin-right: ${space(1)}; `;