// eslint-disable-next-line no-restricted-imports import {withRouter, WithRouterProps} from 'react-router'; import styled from '@emotion/styled'; import AsyncComponent from 'sentry/components/asyncComponent'; import {AreaChart} from 'sentry/components/charts/areaChart'; import ChartZoom from 'sentry/components/charts/chartZoom'; import {HeaderTitleLegend, SectionHeading} from 'sentry/components/charts/styles'; import type {DateTimeObject} from 'sentry/components/charts/utils'; import {Panel, PanelBody, PanelFooter} from 'sentry/components/panels'; import Placeholder from 'sentry/components/placeholder'; import {t} from 'sentry/locale'; import space from 'sentry/styles/space'; import {Organization, Project} from 'sentry/types'; import {IssueAlertRule, ProjectAlertRuleStats} from 'sentry/types/alerts'; import getDynamicText from 'sentry/utils/getDynamicText'; type Props = AsyncComponent['props'] & DateTimeObject & WithRouterProps & { orgId: string; organization: Organization; project: Project; rule: IssueAlertRule; }; type State = AsyncComponent['state'] & { ruleFireHistory: ProjectAlertRuleStats[]; }; class AlertChart extends AsyncComponent { componentDidUpdate(prevProps: Props) { const {project, organization, start, end, period, utc} = this.props; if ( prevProps.start !== start || prevProps.end !== end || prevProps.period !== period || prevProps.utc !== utc || prevProps.organization.id !== organization.id || prevProps.project.id !== project.id ) { this.remountComponent(); } } getDefaultState(): State { return { ...super.getDefaultState(), ruleFireHistory: [], }; } getEndpoints(): ReturnType { const {project, organization, period, start, end, utc, rule} = this.props; return [ [ 'ruleFireHistory', `/projects/${organization.slug}/${project.slug}/rules/${rule.id}/stats/`, { query: { ...(period && {statsPeriod: period}), start, end, utc, }, }, ], ]; } renderChart() { const {router, period, start, end, utc} = this.props; const {ruleFireHistory} = this.state; const series = { seriesName: 'Alerts Triggered', data: ruleFireHistory.map(alert => ({ name: alert.date, value: alert.count, })), emphasis: { disabled: true, }, }; return ( {zoomRenderProps => ( )} ); } renderEmpty() { return ( ); } render() { const {ruleFireHistory, loading} = this.state; const totalAlertsTriggered = ruleFireHistory.reduce( (acc, curr) => acc + curr.count, 0 ); return loading ? ( this.renderEmpty() ) : ( {t('Alerts Triggered')} {getDynamicText({ value: this.renderChart(), fixed: , })} {t('Total Alerts')} {totalAlertsTriggered.toLocaleString()} ); } } export default withRouter(AlertChart); const ChartHeader = styled('div')` margin-bottom: ${space(3)}; `; const ChartFooter = styled(PanelFooter)` display: flex; align-items: center; padding: ${space(1)} 20px; `; const FooterHeader = styled(SectionHeading)` display: flex; align-items: center; margin: 0; font-weight: bold; font-size: ${p => p.theme.fontSizeMedium}; line-height: 1; `; const FooterValue = styled('div')` display: flex; align-items: center; margin: 0 ${space(1)}; `; /* Override padding to make chart appear centered */ const StyledPanelBody = styled(PanelBody)` padding-right: 6px; `;