123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- import {Fragment, useMemo} from 'react';
- import {useTheme} from '@emotion/react';
- import moment from 'moment-timezone';
- import Legend from 'sentry/components/charts/components/legend';
- import {usePageFilterDates} from 'sentry/components/checkInTimeline/hooks/useMonitorDates';
- import {DateTime} from 'sentry/components/dateTime';
- import {t} from 'sentry/locale';
- import type {Series} from 'sentry/types/echarts';
- import type {Event} from 'sentry/types/event';
- import type {GroupOpenPeriod} from 'sentry/types/group';
- import {useApiQuery} from 'sentry/utils/queryClient';
- import useOrganization from 'sentry/utils/useOrganization';
- import {useUser} from 'sentry/utils/useUser';
- import type {TimePeriodType} from 'sentry/views/alerts/rules/metric/details/constants';
- import {type MetricRule, TimePeriod} from 'sentry/views/alerts/rules/metric/types';
- import {useIssueDetails} from 'sentry/views/issueDetails/streamline/context';
- import {getGroupEventQueryKey} from 'sentry/views/issueDetails/utils';
- export function useMetricIssueAlertId({groupId}: {groupId: string}): string | undefined {
- /**
- * This should be removed once the metric alert rule ID is set on the issue.
- * This will fetch an event from the max range if the detector details
- * are not available (e.g. time range has changed and page refreshed)
- */
- const user = useUser();
- const organization = useOrganization();
- const {detectorDetails} = useIssueDetails();
- const {detectorId, detectorType} = detectorDetails;
- const hasMetricDetector = detectorId && detectorType === 'metric_alert';
- const {data: event} = useApiQuery<Event>(
- getGroupEventQueryKey({
- orgSlug: organization.slug,
- groupId,
- eventId: user.options.defaultIssueEvent,
- environments: [],
- }),
- {
- staleTime: Infinity,
- enabled: !hasMetricDetector,
- retry: false,
- }
- );
- // Fall back to the fetched event in case the provider doesn't have the detector details
- return hasMetricDetector ? detectorId : event?.contexts?.metric_alert?.alert_rule_id;
- }
- interface UseMetricTimePeriodParams {
- openPeriod?: GroupOpenPeriod;
- }
- export function useMetricTimePeriod({
- openPeriod,
- }: UseMetricTimePeriodParams = {}): TimePeriodType {
- const {since, until} = usePageFilterDates();
- return useMemo(() => {
- const start = openPeriod?.start ?? since.toISOString();
- let end = openPeriod?.end ?? until.toISOString();
- if (!end) {
- end = new Date().toISOString();
- }
- return {
- start,
- end,
- period: TimePeriod.SEVEN_DAYS,
- usingPeriod: false,
- label: t('Custom time'),
- display: (
- <Fragment>
- <DateTime date={moment.utc(start)} />
- {' — '}
- <DateTime date={moment.utc(end)} />
- </Fragment>
- ),
- custom: true,
- };
- }, [openPeriod, since, until]);
- }
- export function useMetricIssueLegend({
- rule,
- series,
- }: {
- rule: MetricRule;
- series: Series[];
- }) {
- const theme = useTheme();
- return useMemo(() => {
- const legendSet = new Set(series.map(s => s.seriesName));
- if (legendSet.has(rule.aggregate)) {
- legendSet.delete(rule.aggregate);
- }
- const legendItems = Array.from(legendSet).map(name => {
- switch (name) {
- case 'Threshold Line':
- return {
- name,
- icon: HORIZONTAL_DASHED_LINE_CHART_ICON,
- itemStyle: {
- color: theme.error,
- },
- };
- case 'Incident Line':
- return {
- name,
- icon: VERTICAL_LINE_CHART_ICON,
- itemStyle: {
- color: theme.error,
- },
- };
- case 'Status Area':
- return {
- name,
- icon: HORIZONTAL_BAR_CHART_ICON,
- itemStyle: {
- color: theme.error,
- },
- };
- default:
- return {
- name,
- icon: 'circle',
- color: theme.gray300,
- };
- }
- });
- return Legend({
- theme,
- orient: 'horizontal',
- align: 'left',
- show: true,
- data: legendItems,
- inactiveColor: theme.gray200,
- });
- }, [rule, series, theme]);
- }
- /**
- * The legend icon for the dashed horizontal lines in a chart, commonly for thresholds.
- */
- const HORIZONTAL_DASHED_LINE_CHART_ICON =
- 'path://M180 1000 l0 -80 200 0 200 0 0 80 0 80 -200 0 -200 0 0 -80z, M810 1000 l0 -80 200 0 200 0 0 80 0 80 -200 0 -200 0 0 -80zm, M1440 1000 l0 -80 200 0 200 0 0 80 0 80 -200 0 -200 0 0 -80z';
- /**
- * The legend icon for the vertical lines in a chart, commonly for incidents, or releases.
- */
- const VERTICAL_LINE_CHART_ICON =
- 'path://M1000 180 l0 -40 40 0 40 0 0 200 0 200 0 200 0 200 -40 0 -40 0 0 -200 0 -200 0 -200 0 -200z';
- /**
- * The legend icon for the thick horizontal bar along y=0 in a chart, commonly for status areas in metric alerts.
- */
- const HORIZONTAL_BAR_CHART_ICON =
- 'path://M180 1000 l0 -160 400 0 400 0 0 160 0 160 -400 0 -400 0 0 -160z';
|