Skip to content

Commit

Permalink
chore(alerts): Remove fe code for activated alerts (#81218)
Browse files Browse the repository at this point in the history
Remove the front end for activated alerts as it's being deprecated. I
can't merge this until we clean up a couple live alerts but I wanted to
get the PRs ready. The gigantic backend counterpart is here
#81095

**Before**
<img width="1096" alt="Screenshot 2024-11-25 at 1 25 54 PM"
src="https://github.com/user-attachments/assets/8d3fdbc2-59d9-4c38-9032-cf89f56e9153">


**After**
<img width="1078" alt="Screenshot 2024-11-25 at 1 27 26 PM"
src="https://github.com/user-attachments/assets/6d7d5191-285d-465a-9eda-a8441958e8bd">
  • Loading branch information
ceorourke authored Jan 6, 2025
1 parent 60cb2d7 commit 8ff2196
Show file tree
Hide file tree
Showing 3 changed files with 2 additions and 349 deletions.
189 changes: 1 addition & 188 deletions static/app/views/alerts/rules/metric/ruleConditionsForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ import {SearchQueryBuilder} from 'sentry/components/searchQueryBuilder';
import {InvalidReason} from 'sentry/components/searchSyntax/parser';
import {t, tct} from 'sentry/locale';
import {space} from 'sentry/styles/space';
import {ActivationConditionType, MonitorType} from 'sentry/types/alerts';
import type {SelectValue} from 'sentry/types/core';
import type {Tag, TagCollection} from 'sentry/types/group';
import type {InjectedRouter} from 'sentry/types/legacyReactRouter';
Expand Down Expand Up @@ -105,12 +104,6 @@ type Props = {
isEditing: boolean;
onComparisonDeltaChange: (value: number) => void;
onFilterSearch: (query: string, isQueryValid) => void;
onMonitorTypeSelect: (activatedAlertFields: {
activationCondition?: ActivationConditionType | undefined;
monitorType?: MonitorType;
monitorWindowSuffix?: string | undefined;
monitorWindowValue?: number | undefined;
}) => void;
onTimeWindowChange: (value: number) => void;
organization: Organization;
project: Project;
Expand All @@ -120,7 +113,6 @@ type Props = {
thresholdChart: React.ReactNode;
timeWindow: number;
// optional props
activationCondition?: ActivationConditionType;
allowChangeEventTypes?: boolean;
comparisonDelta?: number;
disableProjectSelector?: boolean;
Expand All @@ -130,7 +122,6 @@ type Props = {
isLowConfidenceChartData?: boolean;
isTransactionMigration?: boolean;
loadingProjects?: boolean;
monitorType?: number;
};

type State = {
Expand Down Expand Up @@ -499,16 +490,7 @@ class RuleConditionsForm extends PureComponent<Props, State> {
}

renderInterval() {
const {
organization,
disabled,
alertType,
timeWindow,
onTimeWindowChange,
project,
monitorType,
isForLlmMetric,
} = this.props;
const {organization, disabled, alertType, project, isForLlmMetric} = this.props;

return (
<Fragment>
Expand Down Expand Up @@ -536,118 +518,6 @@ class RuleConditionsForm extends PureComponent<Props, State> {
required
/>
)}

{monitorType !== MonitorType.ACTIVATED && (
<SelectControl
name="timeWindow"
styles={this.selectControlStyles}
options={this.timeWindowOptions}
required={monitorType === MonitorType.CONTINUOUS}
isDisabled={disabled}
value={timeWindow}
onChange={({value}) => onTimeWindowChange(value)}
inline={false}
flexibleControlStateSize
/>
)}
</FormRow>
</Fragment>
);
}

renderMonitorTypeSelect() {
// TODO: disable select on edit
const {
activationCondition,
isEditing,
monitorType,
onMonitorTypeSelect,
onTimeWindowChange,
timeWindow,
} = this.props;

return (
<Fragment>
<StyledListItem>
<StyledListTitle>
<div>{t('Select Monitor Type')}</div>
</StyledListTitle>
</StyledListItem>
<FormRow>
<MonitorSelect>
<MonitorCard
disabled={isEditing}
position="left"
isSelected={monitorType === MonitorType.CONTINUOUS}
onClick={() =>
isEditing
? null
: onMonitorTypeSelect({
monitorType: MonitorType.CONTINUOUS,
})
}
>
<strong>{t('Continuous')}</strong>
<div>{t('Continuously monitor trends for the metrics outlined below')}</div>
</MonitorCard>
<MonitorCard
disabled={isEditing}
position="right"
isSelected={monitorType === MonitorType.ACTIVATED}
onClick={() =>
isEditing
? null
: onMonitorTypeSelect({
monitorType: MonitorType.ACTIVATED,
})
}
>
<strong>Conditional</strong>
{monitorType === MonitorType.ACTIVATED ? (
<ActivatedAlertFields>
{`${t('Monitor')} `}
<SelectControl
name="activationCondition"
styles={this.selectControlStyles}
disabled={isEditing}
options={[
{
value: ActivationConditionType.RELEASE_CREATION,
label: t('New Release'),
},
{
value: ActivationConditionType.DEPLOY_CREATION,
label: t('New Deploy'),
},
]}
required
value={activationCondition}
onChange={({value}) =>
onMonitorTypeSelect({activationCondition: value})
}
inline={false}
flexibleControlStateSize
size="xs"
/>
{` ${t('for')} `}
<SelectControl
name="timeWindow"
styles={this.selectControlStyles}
options={this.timeWindowOptions}
value={timeWindow}
onChange={({value}) => onTimeWindowChange(value)}
inline={false}
flexibleControlStateSize
size="xs"
/>
</ActivatedAlertFields>
) : (
<div>
{t('Temporarily monitor specified query given activation condition')}
</div>
)}
</MonitorCard>
</MonitorSelect>
</FormRow>
</Fragment>
);
Expand All @@ -671,8 +541,6 @@ class RuleConditionsForm extends PureComponent<Props, State> {
} = this.props;

const {environments, filterKeys} = this.state;
const hasActivatedAlerts = organization.features.includes('activated-alert-rules');

const environmentOptions: SelectValue<string | null>[] = [
{
value: null,
Expand Down Expand Up @@ -718,7 +586,6 @@ class RuleConditionsForm extends PureComponent<Props, State> {
)}
</Alert>
)}
{hasActivatedAlerts && this.renderMonitorTypeSelect()}
{!isErrorMigration && this.renderInterval()}
<StyledListItem>{t('Filter events')}</StyledListItem>
<FormRow noMargin columns={1 + (allowChangeEventTypes ? 1 : 0) + 1}>
Expand Down Expand Up @@ -943,58 +810,4 @@ const FormRow = styled('div')<{columns?: number; noMargin?: boolean}>`
`}
`;

const MonitorSelect = styled('div')`
border-radius: ${p => p.theme.borderRadius};
border: 1px solid ${p => p.theme.border};
width: 100%;
display: grid;
grid-template-columns: 1fr 1fr;
height: 5rem;
`;

type MonitorCardProps = {
isSelected: boolean;
/**
* Adds hover and focus states to the card
*/
position: 'left' | 'right';
disabled?: boolean;
};

const MonitorCard = styled('div')<MonitorCardProps>`
padding: ${space(1)} ${space(2)};
display: flex;
flex-grow: 1;
flex-direction: column;
cursor: ${p => (p.disabled || p.isSelected ? 'default' : 'pointer')};
justify-content: center;
background-color: ${p =>
p.disabled && !p.isSelected ? p.theme.backgroundSecondary : p.theme.background};
&:focus,
&:hover {
${p =>
p.disabled || p.isSelected
? ''
: `
outline: 1px solid ${p.theme.purple200};
background-color: ${p.theme.backgroundSecondary};
`}
}
border-top-left-radius: ${p => (p.position === 'left' ? p.theme.borderRadius : 0)};
border-bottom-left-radius: ${p => (p.position === 'left' ? p.theme.borderRadius : 0)};
border-top-right-radius: ${p => (p.position !== 'left' ? p.theme.borderRadius : 0)};
border-bottom-right-radius: ${p => (p.position !== 'left' ? p.theme.borderRadius : 0)};
margin: ${p =>
p.isSelected ? (p.position === 'left' ? '1px 2px 1px 0' : '1px 0 1px 2px') : 0};
outline: ${p => (p.isSelected ? `2px solid ${p.theme.purple400}` : 'none')};
`;

const ActivatedAlertFields = styled('div')`
display: flex;
align-items: center;
justify-content: space-between;
`;

export default withApi(withProjects(withTags(RuleConditionsForm)));
96 changes: 0 additions & 96 deletions static/app/views/alerts/rules/metric/ruleForm.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import selectEvent from 'sentry-test/selectEvent';
import {addErrorMessage} from 'sentry/actionCreators/indicator';
import type FormModel from 'sentry/components/forms/model';
import ProjectsStore from 'sentry/stores/projectsStore';
import {ActivationConditionType, MonitorType} from 'sentry/types/alerts';
import {metric} from 'sentry/utils/analytics';
import RuleFormContainer from 'sentry/views/alerts/rules/metric/ruleForm';
import {
Expand Down Expand Up @@ -151,23 +150,6 @@ describe('Incident Rules Form', () => {
expect(await screen.findByLabelText('Save Rule')).toBeEnabled();
expect(screen.queryByText(permissionAlertText)).not.toBeInTheDocument();
});

it('renders time window', async () => {
createWrapper({rule});

expect(await screen.findByText('1 hour interval')).toBeInTheDocument();
});

it('renders time window for activated alerts', async () => {
createWrapper({
rule: {
...rule,
monitorType: MonitorType.CONTINUOUS,
},
});

expect(await screen.findByText('1 hour interval')).toBeInTheDocument();
});
});

describe('Creating a new rule', () => {
Expand Down Expand Up @@ -301,84 +283,6 @@ describe('Incident Rules Form', () => {
);
});

// Activation condition
it('creates a rule with an activation condition', async () => {
organization.features = [
...organization.features,
'mep-rollout-flag',
'activated-alert-rules',
];
const rule = MetricRuleFixture({
monitorType: MonitorType.ACTIVATED,
activationCondition: ActivationConditionType.RELEASE_CREATION,
});
createWrapper({
rule: {
...rule,
id: undefined,
aggregate: 'count()',
eventTypes: ['transaction'],
dataset: 'transactions',
},
});

expect(await screen.findByTestId('alert-total-events')).toHaveTextContent('Total5');

await userEvent.click(screen.getByLabelText('Save Rule'));

expect(createRule).toHaveBeenCalledWith(
expect.anything(),
expect.objectContaining({
data: expect.objectContaining({
name: 'My Incident Rule',
projects: ['project-slug'],
aggregate: 'count()',
eventTypes: ['transaction'],
dataset: 'generic_metrics',
thresholdPeriod: 1,
}),
})
);
});

it('creates a continuous rule with activated rules enabled', async () => {
organization.features = [
...organization.features,
'mep-rollout-flag',
'activated-alert-rules',
];
const rule = MetricRuleFixture({
monitorType: MonitorType.CONTINUOUS,
});
createWrapper({
rule: {
...rule,
id: undefined,
aggregate: 'count()',
eventTypes: ['transaction'],
dataset: 'transactions',
},
});

expect(await screen.findByTestId('alert-total-events')).toHaveTextContent('Total5');

await userEvent.click(screen.getByLabelText('Save Rule'));

expect(createRule).toHaveBeenCalledWith(
expect.anything(),
expect.objectContaining({
data: expect.objectContaining({
name: 'My Incident Rule',
projects: ['project-slug'],
aggregate: 'count()',
eventTypes: ['transaction'],
dataset: 'generic_metrics',
thresholdPeriod: 1,
}),
})
);
});

it('creates an anomaly detection rule', async () => {
organization.features = [
...organization.features,
Expand Down
Loading

0 comments on commit 8ff2196

Please sign in to comment.