Skip to content

Commit c167068

Browse files
authored
feat(workflow): Remove "Create incident" manual workflow and e… (#16375)
This removes the UI and endpoint to create a manual incident.
1 parent d805fe0 commit c167068

File tree

11 files changed

+6
-637
lines changed

11 files changed

+6
-637
lines changed

src/sentry/api/endpoints/organization_incident_index.py

+1-33
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
from __future__ import absolute_import
22

33
from rest_framework import serializers
4-
from rest_framework.exceptions import PermissionDenied
5-
from rest_framework.response import Response
64

75
from sentry import features
86
from sentry.api.bases.incident import IncidentPermission
@@ -11,8 +9,7 @@
119
from sentry.api.paginator import OffsetPaginator
1210
from sentry.api.serializers import serialize
1311
from sentry.api.serializers.rest_framework import ListField
14-
from sentry.incidents.logic import create_incident
15-
from sentry.incidents.models import Incident, IncidentStatus, IncidentType
12+
from sentry.incidents.models import Incident, IncidentStatus
1613
from sentry.models.group import Group
1714
from sentry.models.project import Project
1815
from sentry.snuba.models import QueryAggregations
@@ -84,32 +81,3 @@ def get(self, request, organization):
8481
on_results=lambda x: serialize(x, request.user),
8582
default_per_page=25,
8683
)
87-
88-
def post(self, request, organization):
89-
if not features.has("organizations:incidents", organization, actor=request.user):
90-
return self.respond(status=404)
91-
92-
serializer = IncidentSerializer(data=request.data, context={"organization": organization})
93-
94-
if serializer.is_valid():
95-
96-
result = serializer.validated_data
97-
groups = result["groups"]
98-
all_projects = set(result["projects"]) | set(g.project for g in result["groups"])
99-
if any(p for p in all_projects if not request.access.has_project_access(p)):
100-
raise PermissionDenied
101-
102-
incident = create_incident(
103-
organization=organization,
104-
type=IncidentType.CREATED,
105-
title=result["title"],
106-
query=result.get("query", ""),
107-
aggregation=result["aggregation"],
108-
date_started=result.get("dateStarted"),
109-
date_detected=result.get("dateDetected"),
110-
projects=result["projects"],
111-
groups=groups,
112-
user=request.user,
113-
)
114-
return Response(serialize(incident, request.user), status=201)
115-
return Response(serializer.errors, status=400)

src/sentry/static/sentry/app/actionCreators/incident.jsx

+1-36
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,6 @@
1-
import {
2-
addErrorMessage,
3-
addLoadingMessage,
4-
clearIndicators,
5-
} from 'app/actionCreators/indicator';
1+
import {addErrorMessage, clearIndicators} from 'app/actionCreators/indicator';
62
import {t} from 'app/locale';
73

8-
/**
9-
* Creates a new incident
10-
*
11-
* @param {Object} api API Client
12-
* @param {Object} organization Organization object
13-
* @param {String} title Title of the incident
14-
* @param {String[]} groups List of group ids
15-
*/
16-
export async function createIncident(api, organization, title, groups) {
17-
addLoadingMessage(t('Creating new incident...'));
18-
19-
try {
20-
const resp = await api.requestPromise(
21-
`/organizations/${organization.slug}/incidents/`,
22-
{
23-
method: 'POST',
24-
data: {
25-
title,
26-
groups,
27-
query: '',
28-
},
29-
}
30-
);
31-
clearIndicators();
32-
return resp;
33-
} catch (err) {
34-
addErrorMessage(t('Unable to create incident'));
35-
throw err;
36-
}
37-
}
38-
394
/**
405
* Fetches a list of activities for an incident
416
*/

src/sentry/static/sentry/app/actionCreators/modal.tsx

-14
Original file line numberDiff line numberDiff line change
@@ -100,20 +100,6 @@ export function openDiffModal(options: ModalOptions) {
100100
});
101101
}
102102

103-
/**
104-
* @param Object options
105-
* @param Object options.organization The organization to create a team for
106-
*/
107-
export function openCreateIncidentModal(options: ModalOptions = {}) {
108-
import(/* webpackChunkName: "CreateIncidentModal" */ 'app/components/modals/createIncidentModal')
109-
.then(mod => mod.default)
110-
.then(Modal => {
111-
openModal(deps => (
112-
<Modal data-test-id="create-incident-modal" {...deps} {...options} />
113-
));
114-
});
115-
}
116-
117103
/**
118104
* @param Object options
119105
* @param Object options.organization The organization to create a team for

src/sentry/static/sentry/app/components/modals/createIncidentModal.jsx

-88
This file was deleted.

src/sentry/static/sentry/app/views/incidents/list/index.tsx

+1-13
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ import styled from 'react-emotion';
88

99
import {PageContent, PageHeader} from 'app/styles/organization';
1010
import {Panel, PanelBody, PanelHeader, PanelItem} from 'app/components/panels';
11-
import {t, tct} from 'app/locale';
12-
import AlertLink from 'app/components/alertLink';
11+
import {t} from 'app/locale';
1312
import AsyncComponent from 'app/components/asyncComponent';
1413
import BetaTag from 'app/components/betaTag';
1514
import Button from 'app/components/button';
@@ -175,17 +174,6 @@ class IncidentsListContainer extends React.Component<Props> {
175174
</Actions>
176175
</PageHeader>
177176

178-
<AlertLink
179-
priority="info"
180-
to={`/organizations/${orgId}/issues/`}
181-
icon="icon-circle-info"
182-
>
183-
{tct(
184-
'To create a new Incident, select one or more issues from the Issues view. Then, click the [create:Create Incident] button.',
185-
{create: <em />}
186-
)}
187-
</AlertLink>
188-
189177
<IncidentsList {...this.props} />
190178
</PageContent>
191179
</DocumentTitle>

src/sentry/static/sentry/app/views/issueList/actions.jsx

-53
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,16 @@ import Reflux from 'reflux';
66
import createReactClass from 'create-react-class';
77
import styled from 'react-emotion';
88

9-
import {openCreateIncidentModal} from 'app/actionCreators/modal';
109
import {t, tct, tn} from 'app/locale';
1110
import space from 'app/styles/space';
1211
import theme from 'app/utils/theme';
1312
import ActionLink from 'app/components/actions/actionLink';
1413
import Checkbox from 'app/components/checkbox';
1514
import DropdownLink from 'app/components/dropdownLink';
1615
import ExternalLink from 'app/components/links/externalLink';
17-
import Feature from 'app/components/acl/feature';
1816
import GroupStore from 'app/stores/groupStore';
1917
import IgnoreActions from 'app/components/actions/ignore';
2018
import IndicatorStore from 'app/stores/indicatorStore';
21-
import InlineSvg from 'app/components/inlineSvg';
2219
import MenuItem from 'app/components/menuItem';
2320
import Projects from 'app/utils/projects';
2421
import ResolveActions from 'app/components/actions/resolve';
@@ -156,7 +153,6 @@ const IssueListActions = createReactClass({
156153
statsPeriod: PropTypes.string.isRequired,
157154
query: PropTypes.string.isRequired,
158155
queryCount: PropTypes.number,
159-
organization: SentryTypes.Organization,
160156
},
161157

162158
mixins: [Reflux.listenTo(SelectedGroupStore, 'handleSelectedGroupChange')],
@@ -315,12 +311,6 @@ const IssueListActions = createReactClass({
315311
});
316312
},
317313

318-
handleCreateIncident() {
319-
const {organization} = this.props;
320-
const issues = this.state.selectedIds;
321-
openCreateIncidentModal({organization, issues: Array.from(issues)});
322-
},
323-
324314
handleSelectAll() {
325315
SelectedGroupStore.toggleSelectAll();
326316
},
@@ -404,7 +394,6 @@ const IssueListActions = createReactClass({
404394
// merges require a single project to be active in an org context
405395
// selectedProjectSlug is null when 0 or >1 projects are selected.
406396
const mergeDisabled = !(multiSelected && selectedProjectSlug);
407-
const createNewIncidentDisabled = !anySelected || allInQuerySelected;
408397

409398
return (
410399
<Sticky>
@@ -457,25 +446,6 @@ const IssueListActions = createReactClass({
457446
{t('Merge')}
458447
</ActionLink>
459448
</div>
460-
<Feature features={['incidents']}>
461-
<div className="btn-group hidden-xs">
462-
<ActionLink
463-
className="btn btn-default btn-sm hidden-md hidden-sm hidden-xs"
464-
title={t('Create new incident')}
465-
disabled={createNewIncidentDisabled}
466-
onAction={this.handleCreateIncident}
467-
>
468-
<IncidentLabel>
469-
<IncidentIcon
470-
data-test-id="create-incident"
471-
size="16"
472-
src="icon-siren-add"
473-
/>
474-
<CreateIncidentText>{t('Create Incident')}</CreateIncidentText>
475-
</IncidentLabel>
476-
</ActionLink>
477-
</div>
478-
</Feature>
479449
<div className="btn-group">
480450
<DropdownLink
481451
key="actions"
@@ -498,17 +468,6 @@ const IssueListActions = createReactClass({
498468
</ActionLink>
499469
</MenuItem>
500470
<MenuItem divider className="hidden-lg hidden-xl" />
501-
<MenuItem noAnchor>
502-
<ActionLink
503-
className="hidden-lg hidden-xl"
504-
disabled={createNewIncidentDisabled}
505-
onAction={this.handleCreateIncident}
506-
title={t('Create new incident')}
507-
>
508-
{t('Create Incident')}
509-
</ActionLink>
510-
</MenuItem>
511-
<MenuItem divider className="hidden-lg hidden-xl" />
512471
<MenuItem noAnchor>
513472
<ActionLink
514473
className="action-bookmark"
@@ -749,18 +708,6 @@ const AssigneesLabel = styled('div')`
749708
margin-right: ${space(2)};
750709
`;
751710

752-
const IncidentLabel = styled('div')`
753-
display: flex;
754-
align-items: center;
755-
`;
756-
const IncidentIcon = styled(InlineSvg)`
757-
position: relative;
758-
top: -1px;
759-
`;
760-
const CreateIncidentText = styled('span')`
761-
margin-left: 5px; /* consistent with other items in bar */
762-
`;
763-
764711
export {IssueListActions};
765712

766713
export default withApi(IssueListActions);

tests/acceptance/test_incidents.py

+1-24
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@
22

33
from django.utils import timezone
44
import pytz
5-
from mock import patch
65

76
from sentry.testutils import AcceptanceTestCase, SnubaTestCase
8-
from sentry.testutils.helpers.datetime import iso_format, before_now
7+
from sentry.testutils.helpers.datetime import before_now
98
from sentry.incidents.logic import create_incident
109
from sentry.incidents.models import IncidentType
1110
from sentry.snuba.models import QueryAggregations
@@ -54,25 +53,3 @@ def test_incidents_list(self):
5453

5554
self.browser.wait_until_not('[data-test-id="loading-placeholder"]')
5655
self.browser.snapshot("incidents - details")
57-
58-
@patch("django.utils.timezone.now")
59-
def test_open_create_incident_modal(self, mock_now):
60-
mock_now.return_value = before_now().replace(tzinfo=pytz.utc)
61-
self.store_event(
62-
data={
63-
"event_id": "a" * 32,
64-
"message": "oh no",
65-
"timestamp": iso_format(event_time),
66-
"fingerprint": ["group-1"],
67-
},
68-
project_id=self.project.id,
69-
)
70-
71-
with self.feature(FEATURE_NAME):
72-
self.browser.get(u"/organizations/{}/issues/".format(self.organization.slug))
73-
self.browser.wait_until_not(".loading-indicator")
74-
self.browser.wait_until_test_id("group")
75-
self.browser.click('[data-test-id="group"]')
76-
self.browser.click('[data-test-id="action-link-create-new-incident"]')
77-
self.browser.wait_until_test_id("create-new-incident-form")
78-
# TODO: Figure out how to deal with mocked dates

0 commit comments

Comments
 (0)