Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(alerts): Remove fe code for activated alerts #81218

Merged
merged 3 commits into from
Jan 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -486,16 +477,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 @@ -523,118 +505,6 @@ class RuleConditionsForm extends PureComponent<Props, State> {
required
/>
)}

{monitorType !== MonitorType.ACTIVATED && (
ceorourke marked this conversation as resolved.
Show resolved Hide resolved
<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 @@ -658,8 +528,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 @@ -705,7 +573,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 @@ -935,58 +802,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
Loading