123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- import styled from '@emotion/styled';
- import type {PromptResponse} from 'sentry/actionCreators/prompts';
- import {
- makePromptsCheckQueryKey,
- promptsUpdate,
- usePromptsCheck,
- } from 'sentry/actionCreators/prompts';
- import Alert from 'sentry/components/alert';
- import {Button, LinkButton} from 'sentry/components/button';
- import ButtonBar from 'sentry/components/buttonBar';
- import {IconClose, IconEdit} from 'sentry/icons';
- import {t} from 'sentry/locale';
- import type {Project} from 'sentry/types';
- import {promptIsDismissed} from 'sentry/utils/promptIsDismissed';
- import {setApiQueryData, useQueryClient} from 'sentry/utils/queryClient';
- import useApi from 'sentry/utils/useApi';
- import useOrganization from 'sentry/utils/useOrganization';
- import type {MetricRule} from 'sentry/views/alerts/rules/metric/types';
- import {
- hasIgnoreArchivedFeatureFlag,
- ruleNeedsErrorMigration,
- } from 'sentry/views/alerts/utils/migrationUi';
- interface ErrorMigrationWarningProps {
- project?: Project;
- rule?: MetricRule;
- }
- const METRIC_ALERT_IGNORE_ARCHIVED_ISSUES = 'metric_alert_ignore_archived_issues';
- function createdOrModifiedAfterMigration(rule: MetricRule) {
- const migrationDate = new Date('2023-12-11T00:00:00Z').getTime();
- return (
- (rule.dateCreated && new Date(rule.dateCreated).getTime() > migrationDate) ||
- (rule.dateModified && new Date(rule.dateModified).getTime() > migrationDate)
- );
- }
- /**
- * Displays a message to filter events from archived issues when the metric alert
- * is counting error events.
- */
- export function ErrorMigrationWarning({project, rule}: ErrorMigrationWarningProps) {
- const api = useApi();
- const organization = useOrganization();
- const queryClient = useQueryClient();
- const showErrorMigrationWarning =
- rule && hasIgnoreArchivedFeatureFlag(organization) && ruleNeedsErrorMigration(rule);
- const isCreatedAfterMigration = rule && createdOrModifiedAfterMigration(rule);
- const prompt = usePromptsCheck(
- {
- organization,
- feature: METRIC_ALERT_IGNORE_ARCHIVED_ISSUES,
- projectId: project?.id,
- },
- {staleTime: Infinity, enabled: showErrorMigrationWarning && !isCreatedAfterMigration}
- );
- const isPromptDismissed =
- prompt.isSuccess && prompt.data.data
- ? promptIsDismissed({
- dismissedTime: prompt.data.data.dismissed_ts,
- snoozedTime: prompt.data.data.snoozed_ts,
- })
- : false;
- if (
- !showErrorMigrationWarning ||
- !rule ||
- isPromptDismissed ||
- isCreatedAfterMigration
- ) {
- return null;
- }
- const dismissPrompt = () => {
- promptsUpdate(api, {
- organization,
- projectId: project?.id,
- feature: METRIC_ALERT_IGNORE_ARCHIVED_ISSUES,
- status: 'dismissed',
- });
- // Update cached query data, set to dismissed
- setApiQueryData<PromptResponse>(
- queryClient,
- makePromptsCheckQueryKey({
- organization,
- feature: METRIC_ALERT_IGNORE_ARCHIVED_ISSUES,
- projectId: project?.id,
- }),
- () => {
- const dimissedTs = new Date().getTime() / 1000;
- return {
- data: {dismissed_ts: dimissedTs},
- features: {[METRIC_ALERT_IGNORE_ARCHIVED_ISSUES]: {dismissed_ts: dimissedTs}},
- };
- }
- );
- };
- return (
- <Alert
- type="warning"
- showIcon
- trailingItems={
- <ButtonBar gap={1}>
- <LinkButton
- to={{
- pathname: `/organizations/${organization.slug}/alerts/metric-rules/${
- project?.slug ?? rule?.projects?.[0]
- }/${rule.id}/`,
- query: {migration: '1'},
- }}
- size="xs"
- icon={<IconEdit />}
- >
- {t('Exclude archived issues')}
- </LinkButton>
- <DismissButton
- priority="link"
- icon={<IconClose />}
- onClick={dismissPrompt}
- aria-label={t('Dismiss Alert')}
- title={t('Dismiss Alert')}
- />
- </ButtonBar>
- }
- >
- {t(
- "Alert rules can now exclude errors associated with archived issues. Please make sure to review the rule's alert thresholds after editing."
- )}
- </Alert>
- );
- }
- const DismissButton = styled(Button)`
- color: ${p => p.theme.alert.warning.iconColor};
- pointer-events: all;
- &:hover {
- color: ${p => p.theme.alert.warning.iconHoverColor};
- opacity: 0.5;
- }
- `;
|