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 (
{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)};
`;