Browse Source

DO NOT MERGE feat(notification platform): Remove feature flag (#28328)

* feat(notification platform): Remove feature flag
Colleen O'Rourke 3 years ago
parent
commit
95301b090b

+ 0 - 10
src/sentry/api/endpoints/team_notification_settings_details.py

@@ -2,9 +2,7 @@ from rest_framework import status
 from rest_framework.request import Request
 from rest_framework.response import Response
 
-from sentry import features
 from sentry.api.bases.team import TeamEndpoint
-from sentry.api.exceptions import ResourceDoesNotExist
 from sentry.api.serializers import serialize
 from sentry.api.serializers.models.notification_setting import NotificationSettingsSerializer
 from sentry.api.validators.notifications import validate, validate_type_option
@@ -25,10 +23,6 @@ class TeamNotificationSettingsDetailsEndpoint(TeamEndpoint):
         :qparam string type: If set, filter the NotificationSettings to this type.
         :auth required:
         """
-        if not features.has(
-            "organizations:notification-platform", team.organization, actor=request.user
-        ):
-            raise ResourceDoesNotExist
 
         type_option = validate_type_option(request.GET.get("type"))
 
@@ -70,10 +64,6 @@ class TeamNotificationSettingsDetailsEndpoint(TeamEndpoint):
 
         :auth required:
         """
-        if not features.has(
-            "organizations:notification-platform", team.organization, actor=request.user
-        ):
-            raise ResourceDoesNotExist
 
         notification_settings = validate(request.data, team=team)
         NotificationSetting.objects.update_settings_bulk(notification_settings, team=team)

+ 0 - 11
src/sentry/api/endpoints/user_notification_settings_details.py

@@ -3,21 +3,12 @@ from rest_framework.request import Request
 from rest_framework.response import Response
 
 from sentry.api.bases.user import UserEndpoint
-from sentry.api.exceptions import ResourceDoesNotExist
 from sentry.api.serializers import serialize
 from sentry.api.serializers.models.notification_setting import NotificationSettingsSerializer
 from sentry.api.validators.notifications import validate, validate_type_option
-from sentry.features.helpers import any_organization_has_feature
 from sentry.models import NotificationSetting, User
 
 
-def validate_has_feature(user: User) -> None:
-    if not any_organization_has_feature(
-        "organizations:notification-platform", user.get_orgs(), actor=user
-    ):
-        raise ResourceDoesNotExist
-
-
 class UserNotificationSettingsDetailsEndpoint(UserEndpoint):
     """
     This Notification Settings endpoint is the generic way to interact with the
@@ -36,7 +27,6 @@ class UserNotificationSettingsDetailsEndpoint(UserEndpoint):
 
         :auth required:
         """
-        validate_has_feature(user)
 
         type_option = validate_type_option(request.GET.get("type"))
 
@@ -84,7 +74,6 @@ class UserNotificationSettingsDetailsEndpoint(UserEndpoint):
 
         :auth required:
         """
-        validate_has_feature(user)
 
         notification_settings = validate(request.data, user=user)
         NotificationSetting.objects.update_settings_bulk(notification_settings, user=user)

+ 0 - 3
src/sentry/conf/server.py

@@ -1021,9 +1021,6 @@ SENTRY_FEATURES = {
     "organizations:relay": True,
     # Enable Session Stats down to a minute resolution
     "organizations:minute-resolution-sessions": False,
-    # Enable option to send alert, workflow, and deploy notifications
-    # to 3rd parties (e.g. Slack) in addition to email
-    "organizations:notification-platform": False,
     # Automatically opt IN users to receiving Slack notifications.
     "organizations:notification-slack-automatic": False,
     # Enable version 2 of reprocessing (completely distinct from v1)

+ 0 - 1
src/sentry/features/__init__.py

@@ -108,7 +108,6 @@ default_manager.add("organizations:metrics-extraction", OrganizationFeature)
 default_manager.add("organizations:minute-resolution-sessions", OrganizationFeature)
 default_manager.add("organizations:mobile-screenshots", OrganizationFeature, True)
 default_manager.add("organizations:monitors", OrganizationFeature)
-default_manager.add("organizations:notification-platform", OrganizationFeature, True)
 default_manager.add("organizations:notification-slack-automatic", OrganizationFeature, True)
 default_manager.add("organizations:onboarding", OrganizationFeature)
 default_manager.add("organizations:org-subdomains", OrganizationFeature)

+ 0 - 11
src/sentry/integrations/slack/endpoints/base.py

@@ -4,7 +4,6 @@ from typing import Any, Sequence, Tuple
 from rest_framework.response import Response
 
 from sentry.api.base import Endpoint
-from sentry.features.helpers import any_organization_has_feature
 from sentry.integrations.slack.message_builder.help import SlackHelpMessageBuilder
 from sentry.integrations.slack.requests.base import SlackRequest
 from sentry.integrations.slack.views.link_identity import build_linking_url
@@ -17,7 +16,6 @@ LINK_USER_MESSAGE = (
 UNLINK_USER_MESSAGE = "<{associate_url}|Click here to unlink your identity.>"
 NOT_LINKED_MESSAGE = "You do not have a linked identity to unlink."
 ALREADY_LINKED_MESSAGE = "You are already linked as `{username}`."
-FEATURE_FLAG_MESSAGE = "This feature hasn't been released yet, hang tight."
 
 
 class SlackDMEndpoint(Endpoint, abc.ABC):  # type: ignore
@@ -31,15 +29,6 @@ class SlackDMEndpoint(Endpoint, abc.ABC):  # type: ignore
         if command in ["help", ""]:
             return self.respond(SlackHelpMessageBuilder().build())
 
-        if (
-            not request.integration
-            or command in ["link", "unlink"]
-            and not any_organization_has_feature(
-                "organizations:notification-platform", request.integration.organizations.all()
-            )
-        ):
-            return self.reply(request, FEATURE_FLAG_MESSAGE)
-
         if command == "link":
             if not args:
                 return self.link_user(request)

+ 2 - 4
src/sentry/integrations/slack/integration.py

@@ -4,7 +4,6 @@ from typing import Any, Mapping, Optional, Sequence
 from django.utils.translation import ugettext_lazy as _
 from django.views import View
 
-from sentry import features
 from sentry.identity.pipeline import IdentityProviderPipeline
 from sentry.integrations import (
     FeatureDescription,
@@ -196,6 +195,5 @@ class SlackIntegrationProvider(IntegrationProvider):  # type: ignore
         """
         Create Identity records for an organization's users if their emails match in Sentry and Slack
         """
-        if features.has("organizations:notification-platform", organization):
-            run_args = {"integration": integration, "organization": organization}
-            tasks.link_slack_user_identities.apply_async(kwargs=run_args)
+        run_args = {"integration": integration, "organization": organization}
+        tasks.link_slack_user_identities.apply_async(kwargs=run_args)

+ 0 - 14
src/sentry/integrations/slack/message_builder/event.py

@@ -1,6 +1,5 @@
 from typing import Iterable, List, Optional
 
-from sentry.features.helpers import any_organization_has_feature
 from sentry.integrations.slack.message_builder import SlackBlock, SlackBody
 from sentry.integrations.slack.message_builder.help import SlackHelpMessageBuilder
 from sentry.models import Integration
@@ -8,10 +7,6 @@ from sentry.models import Integration
 from ..utils import logger
 from .help import UNKNOWN_COMMAND_MESSAGE
 
-EVENT_MESSAGE = (
-    "Want to learn more about configuring alerts in Sentry? Check out our documentation."
-)
-
 
 class SlackEventMessageBuilder(SlackHelpMessageBuilder):
     def __init__(self, integration: Integration, command: Optional[str] = None) -> None:
@@ -29,13 +24,4 @@ class SlackEventMessageBuilder(SlackHelpMessageBuilder):
         return blocks
 
     def build(self) -> SlackBody:
-        if not any_organization_has_feature(
-            "organizations:notification-platform", self.integration.organizations.all()
-        ):
-            return self._build_blocks(
-                *self.get_header_block(),
-                self.get_markdown_block(EVENT_MESSAGE),
-                self.get_docs_block(),
-            )
-
         return super().build()

+ 1 - 1
static/app/routes.tsx

@@ -77,7 +77,7 @@ function routes() {
       <Route path="notifications/" name="Notifications">
         <IndexRoute
           componentPromise={() =>
-            import('app/views/settings/account/accountNotifications')
+            import('app/views/settings/account/notifications/notificationSettings')
           }
           component={SafeLazyLoad}
         />

+ 3 - 8
static/app/views/settings/account/accountNotificationFineTuning.tsx

@@ -165,15 +165,10 @@ class AccountNotificationFineTuning extends AsyncView<Props, State> {
   }
 
   renderBody() {
-    const {params, organizations} = this.props;
+    const {params} = this.props;
     const {fineTuneType} = params;
 
-    if (
-      ['alerts', 'deploy', 'workflow'].includes(fineTuneType) &&
-      organizations.some(organization =>
-        organization.features.includes('notification-platform')
-      )
-    ) {
+    if (['alerts', 'deploy', 'workflow'].includes(fineTuneType)) {
       return <NotificationSettingsByType notificationType={fineTuneType} />;
     }
 
@@ -261,4 +256,4 @@ const Heading = styled('div')`
   flex: 1;
 `;
 
-export default withOrganizations(AccountNotificationFineTuning);
+export default AccountNotificationFineTuning;

+ 0 - 118
static/app/views/settings/account/accountNotifications.tsx

@@ -1,118 +0,0 @@
-import styled from '@emotion/styled';
-
-import AlertLink from 'app/components/alertLink';
-import Link from 'app/components/links/link';
-import {PanelFooter} from 'app/components/panels';
-import accountNotificationFields from 'app/data/forms/accountNotificationSettings';
-import {IconChevron, IconMail} from 'app/icons';
-import {t} from 'app/locale';
-import {OrganizationSummary} from 'app/types';
-import withOrganizations from 'app/utils/withOrganizations';
-import AsyncView from 'app/views/asyncView';
-import NotificationSettings from 'app/views/settings/account/notifications/notificationSettings';
-import Form from 'app/views/settings/components/forms/form';
-import JsonForm from 'app/views/settings/components/forms/jsonForm';
-import SettingsPageHeader from 'app/views/settings/components/settingsPageHeader';
-
-const FINE_TUNE_FOOTERS = {
-  [t('Alerts')]: {
-    text: t('Fine tune alerts by project'),
-    path: 'alerts/',
-  },
-  [t('Workflow Notifications')]: {
-    text: t('Fine tune workflow notifications by project'),
-    path: 'workflow/',
-  },
-  [t('Email Routing')]: {
-    text: t('Fine tune email routing by project'),
-    path: 'email/',
-  },
-  [t('Weekly Reports')]: {
-    text: t('Fine tune weekly reports by organization'),
-    path: 'reports/',
-  },
-  [t('Deploy Notifications')]: {
-    text: t('Fine tune deploy notifications by organization'),
-    path: 'deploy/',
-  },
-};
-
-type Props = AsyncView['props'] & {
-  organizations: OrganizationSummary[];
-};
-
-type State = AsyncView['state'] & {
-  data: Record<string, unknown> | null;
-};
-
-class AccountNotifications extends AsyncView<Props, State> {
-  getEndpoints(): ReturnType<AsyncView['getEndpoints']> {
-    return [['data', '/users/me/notifications/']];
-  }
-
-  getTitle() {
-    return 'Notifications';
-  }
-
-  renderBody() {
-    const {organizations} = this.props;
-    if (
-      organizations.some(organization =>
-        organization.features.includes('notification-platform')
-      )
-    ) {
-      return <NotificationSettings />;
-    }
-
-    return (
-      <div>
-        <SettingsPageHeader title="Notifications" />
-        <Form
-          initialData={this.state.data ?? undefined}
-          saveOnBlur
-          apiMethod="PUT"
-          apiEndpoint="/users/me/notifications/"
-        >
-          <JsonForm
-            forms={accountNotificationFields}
-            renderFooter={({title}) => {
-              if (typeof title !== 'string') {
-                return null;
-              }
-              if (FINE_TUNE_FOOTERS[title]) {
-                return <FineTuningFooter {...FINE_TUNE_FOOTERS[title]} />;
-              }
-              return null;
-            }}
-          />
-          <AlertLink to="/settings/account/emails" icon={<IconMail />}>
-            {t('Looking to add or remove an email address? Use the emails panel.')}
-          </AlertLink>
-        </Form>
-      </div>
-    );
-  }
-}
-
-const FineTuneLink = styled(Link)`
-  display: flex;
-  justify-content: space-between;
-  padding: 15px 20px;
-  color: inherit;
-`;
-
-type FooterProps = {
-  path: string;
-  text: string;
-};
-
-const FineTuningFooter = ({path, text}: FooterProps) => (
-  <PanelFooter css={{borderTop: 'none'}}>
-    <FineTuneLink to={`/settings/account/notifications/${path}`}>
-      <span>{text}</span>
-      <IconChevron direction="right" size="15px" />
-    </FineTuneLink>
-  </PanelFooter>
-);
-
-export default withOrganizations(AccountNotifications);

Some files were not shown because too many files changed in this diff