Skip to content

feat(workflow): Remove "Create incident" manual workflow and endpoint #16375

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

Merged
merged 5 commits into from
Jan 10, 2020
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
34 changes: 1 addition & 33 deletions src/sentry/api/endpoints/organization_incident_index.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
from __future__ import absolute_import

from rest_framework import serializers
from rest_framework.exceptions import PermissionDenied
from rest_framework.response import Response

from sentry import features
from sentry.api.bases.incident import IncidentPermission
Expand All @@ -11,8 +9,7 @@
from sentry.api.paginator import OffsetPaginator
from sentry.api.serializers import serialize
from sentry.api.serializers.rest_framework import ListField
from sentry.incidents.logic import create_incident
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm just removing the API endpoint, create_incident is still used

from sentry.incidents.models import Incident, IncidentStatus, IncidentType
from sentry.incidents.models import Incident, IncidentStatus
from sentry.models.group import Group
from sentry.models.project import Project
from sentry.snuba.models import QueryAggregations
Expand Down Expand Up @@ -84,32 +81,3 @@ def get(self, request, organization):
on_results=lambda x: serialize(x, request.user),
default_per_page=25,
)

def post(self, request, organization):
if not features.has("organizations:incidents", organization, actor=request.user):
return self.respond(status=404)

serializer = IncidentSerializer(data=request.data, context={"organization": organization})

if serializer.is_valid():

result = serializer.validated_data
groups = result["groups"]
all_projects = set(result["projects"]) | set(g.project for g in result["groups"])
if any(p for p in all_projects if not request.access.has_project_access(p)):
raise PermissionDenied

incident = create_incident(
organization=organization,
type=IncidentType.CREATED,
title=result["title"],
query=result.get("query", ""),
aggregation=result["aggregation"],
date_started=result.get("dateStarted"),
date_detected=result.get("dateDetected"),
projects=result["projects"],
groups=groups,
user=request.user,
)
return Response(serialize(incident, request.user), status=201)
return Response(serializer.errors, status=400)
37 changes: 1 addition & 36 deletions src/sentry/static/sentry/app/actionCreators/incident.jsx
Original file line number Diff line number Diff line change
@@ -1,41 +1,6 @@
import {
addErrorMessage,
addLoadingMessage,
clearIndicators,
} from 'app/actionCreators/indicator';
import {addErrorMessage, clearIndicators} from 'app/actionCreators/indicator';
import {t} from 'app/locale';

/**
* Creates a new incident
*
* @param {Object} api API Client
* @param {Object} organization Organization object
* @param {String} title Title of the incident
* @param {String[]} groups List of group ids
*/
export async function createIncident(api, organization, title, groups) {
addLoadingMessage(t('Creating new incident...'));

try {
const resp = await api.requestPromise(
`/organizations/${organization.slug}/incidents/`,
{
method: 'POST',
data: {
title,
groups,
query: '',
},
}
);
clearIndicators();
return resp;
} catch (err) {
addErrorMessage(t('Unable to create incident'));
throw err;
}
}

/**
* Fetches a list of activities for an incident
*/
Expand Down
14 changes: 0 additions & 14 deletions src/sentry/static/sentry/app/actionCreators/modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,20 +100,6 @@ export function openDiffModal(options: ModalOptions) {
});
}

/**
* @param Object options
* @param Object options.organization The organization to create a team for
*/
export function openCreateIncidentModal(options: ModalOptions = {}) {
import(/* webpackChunkName: "CreateIncidentModal" */ 'app/components/modals/createIncidentModal')
.then(mod => mod.default)
.then(Modal => {
openModal(deps => (
<Modal data-test-id="create-incident-modal" {...deps} {...options} />
));
});
}

/**
* @param Object options
* @param Object options.organization The organization to create a team for
Expand Down

This file was deleted.

14 changes: 1 addition & 13 deletions src/sentry/static/sentry/app/views/incidents/list/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ import styled from 'react-emotion';

import {PageContent, PageHeader} from 'app/styles/organization';
import {Panel, PanelBody, PanelHeader, PanelItem} from 'app/components/panels';
import {t, tct} from 'app/locale';
import AlertLink from 'app/components/alertLink';
import {t} from 'app/locale';
import AsyncComponent from 'app/components/asyncComponent';
import BetaTag from 'app/components/betaTag';
import Button from 'app/components/button';
Expand Down Expand Up @@ -175,17 +174,6 @@ class IncidentsListContainer extends React.Component<Props> {
</Actions>
</PageHeader>

<AlertLink
priority="info"
to={`/organizations/${orgId}/issues/`}
icon="icon-circle-info"
>
{tct(
'To create a new Incident, select one or more issues from the Issues view. Then, click the [create:Create Incident] button.',
{create: <em />}
)}
</AlertLink>

<IncidentsList {...this.props} />
</PageContent>
</DocumentTitle>
Expand Down
53 changes: 0 additions & 53 deletions src/sentry/static/sentry/app/views/issueList/actions.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,16 @@ import Reflux from 'reflux';
import createReactClass from 'create-react-class';
import styled from 'react-emotion';

import {openCreateIncidentModal} from 'app/actionCreators/modal';
import {t, tct, tn} from 'app/locale';
import space from 'app/styles/space';
import theme from 'app/utils/theme';
import ActionLink from 'app/components/actions/actionLink';
import Checkbox from 'app/components/checkbox';
import DropdownLink from 'app/components/dropdownLink';
import ExternalLink from 'app/components/links/externalLink';
import Feature from 'app/components/acl/feature';
import GroupStore from 'app/stores/groupStore';
import IgnoreActions from 'app/components/actions/ignore';
import IndicatorStore from 'app/stores/indicatorStore';
import InlineSvg from 'app/components/inlineSvg';
import MenuItem from 'app/components/menuItem';
import Projects from 'app/utils/projects';
import ResolveActions from 'app/components/actions/resolve';
Expand Down Expand Up @@ -156,7 +153,6 @@ const IssueListActions = createReactClass({
statsPeriod: PropTypes.string.isRequired,
query: PropTypes.string.isRequired,
queryCount: PropTypes.number,
organization: SentryTypes.Organization,
},

mixins: [Reflux.listenTo(SelectedGroupStore, 'handleSelectedGroupChange')],
Expand Down Expand Up @@ -315,12 +311,6 @@ const IssueListActions = createReactClass({
});
},

handleCreateIncident() {
const {organization} = this.props;
const issues = this.state.selectedIds;
openCreateIncidentModal({organization, issues: Array.from(issues)});
},

handleSelectAll() {
SelectedGroupStore.toggleSelectAll();
},
Expand Down Expand Up @@ -404,7 +394,6 @@ const IssueListActions = createReactClass({
// merges require a single project to be active in an org context
// selectedProjectSlug is null when 0 or >1 projects are selected.
const mergeDisabled = !(multiSelected && selectedProjectSlug);
const createNewIncidentDisabled = !anySelected || allInQuerySelected;

return (
<Sticky>
Expand Down Expand Up @@ -457,25 +446,6 @@ const IssueListActions = createReactClass({
{t('Merge')}
</ActionLink>
</div>
<Feature features={['incidents']}>
<div className="btn-group hidden-xs">
<ActionLink
className="btn btn-default btn-sm hidden-md hidden-sm hidden-xs"
title={t('Create new incident')}
disabled={createNewIncidentDisabled}
onAction={this.handleCreateIncident}
>
<IncidentLabel>
<IncidentIcon
data-test-id="create-incident"
size="16"
src="icon-siren-add"
/>
<CreateIncidentText>{t('Create Incident')}</CreateIncidentText>
</IncidentLabel>
</ActionLink>
</div>
</Feature>
<div className="btn-group">
<DropdownLink
key="actions"
Expand All @@ -498,17 +468,6 @@ const IssueListActions = createReactClass({
</ActionLink>
</MenuItem>
<MenuItem divider className="hidden-lg hidden-xl" />
<MenuItem noAnchor>
<ActionLink
className="hidden-lg hidden-xl"
disabled={createNewIncidentDisabled}
onAction={this.handleCreateIncident}
title={t('Create new incident')}
>
{t('Create Incident')}
</ActionLink>
</MenuItem>
<MenuItem divider className="hidden-lg hidden-xl" />
<MenuItem noAnchor>
<ActionLink
className="action-bookmark"
Expand Down Expand Up @@ -749,18 +708,6 @@ const AssigneesLabel = styled('div')`
margin-right: ${space(2)};
`;

const IncidentLabel = styled('div')`
display: flex;
align-items: center;
`;
const IncidentIcon = styled(InlineSvg)`
position: relative;
top: -1px;
`;
const CreateIncidentText = styled('span')`
margin-left: 5px; /* consistent with other items in bar */
`;

export {IssueListActions};

export default withApi(IssueListActions);
25 changes: 1 addition & 24 deletions tests/acceptance/test_incidents.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@

from django.utils import timezone
import pytz
from mock import patch

from sentry.testutils import AcceptanceTestCase, SnubaTestCase
from sentry.testutils.helpers.datetime import iso_format, before_now
from sentry.testutils.helpers.datetime import before_now
from sentry.incidents.logic import create_incident
from sentry.incidents.models import IncidentType
from sentry.snuba.models import QueryAggregations
Expand Down Expand Up @@ -54,25 +53,3 @@ def test_incidents_list(self):

self.browser.wait_until_not('[data-test-id="loading-placeholder"]')
self.browser.snapshot("incidents - details")

@patch("django.utils.timezone.now")
def test_open_create_incident_modal(self, mock_now):
mock_now.return_value = before_now().replace(tzinfo=pytz.utc)
self.store_event(
data={
"event_id": "a" * 32,
"message": "oh no",
"timestamp": iso_format(event_time),
"fingerprint": ["group-1"],
},
project_id=self.project.id,
)

with self.feature(FEATURE_NAME):
self.browser.get(u"/organizations/{}/issues/".format(self.organization.slug))
self.browser.wait_until_not(".loading-indicator")
self.browser.wait_until_test_id("group")
self.browser.click('[data-test-id="group"]')
self.browser.click('[data-test-id="action-link-create-new-incident"]')
self.browser.wait_until_test_id("create-new-incident-form")
# TODO: Figure out how to deal with mocked dates
Loading