Browse Source

chore(onboarding): clean up messaging integration flag (#79530)

remove `messaging-integration-onboarding` feature flag + logging from
alert creation page
mia hsu 4 months ago
parent
commit
f84ce4a721

+ 0 - 3
static/app/utils/analytics/onboardingAnalyticsEvents.tsx

@@ -32,7 +32,6 @@ export type OnboardingEventParameters = {
     provider_key: string;
   };
   'onboarding.messaging_integration_modal_rendered': {};
-  'onboarding.messaging_integration_steps_refreshed': {};
   'onboarding.next_step_clicked': {
     newOrg: boolean;
     platform: string;
@@ -104,8 +103,6 @@ export const onboardingEventMap: Record<keyof OnboardingEventParameters, string>
     'Onboarding: Messaging Integration Modal Rendered',
   'onboarding.messaging_integration_external_install_clicked':
     'Onboarding: Messaging Integration External Install Clicked',
-  'onboarding.messaging_integration_steps_refreshed':
-    'Onboarding: Messaging Integration Steps Refreshed',
   'onboarding.take_me_to_issues_clicked': 'Onboarding: Take Me to Issues Clicked',
   'onboarding.slack_setup_clicked': 'Onboarding: Slack Setup Clicked',
   'onboarding.next_step_clicked': 'Onboarding: Next Step Clicked',

+ 12 - 0
static/app/views/alerts/create.spec.tsx

@@ -1,4 +1,5 @@
 import {EnvironmentsFixture} from 'sentry-fixture/environments';
+import {GitHubIntegrationProviderFixture} from 'sentry-fixture/githubIntegrationProvider';
 import {GroupsFixture} from 'sentry-fixture/groups';
 import {LocationFixture} from 'sentry-fixture/locationFixture';
 import {OrganizationFixture} from 'sentry-fixture/organization';
@@ -72,6 +73,17 @@ describe('ProjectAlertsCreate', function () {
       method: 'POST',
       body: [],
     });
+    MockApiClient.addMockResponse({
+      url: `/organizations/org-slug/integrations/?integrationType=messaging`,
+      body: [],
+    });
+    const providerKeys = ['slack', 'discord', 'msteams'];
+    providerKeys.forEach(providerKey => {
+      MockApiClient.addMockResponse({
+        url: `/organizations/org-slug/config/integrations/?provider_key=${providerKey}`,
+        body: {providers: [GitHubIntegrationProviderFixture({key: providerKey})]},
+      });
+    });
   });
 
   afterEach(function () {

+ 0 - 7
static/app/views/alerts/rules/issue/addIntegrationRow.tsx

@@ -34,12 +34,6 @@ function AddIntegrationRow({onClick}: Props) {
     });
     onClick();
   };
-  const onSelfHostedClick = () => {
-    trackAnalytics('onboarding.messaging_integration_self_hosted_clicked', {
-      provider_key: provider.key,
-      organization,
-    });
-  };
 
   const buttonProps = {
     size: 'sm',
@@ -60,7 +54,6 @@ function AddIntegrationRow({onClick}: Props) {
               href={`https://develop.sentry.dev/integrations/${provider.slug}`}
               priority="primary"
               external
-              onClick={onSelfHostedClick}
             >
               Add {provider.metadata.noun}
             </LinkButton>

+ 12 - 0
static/app/views/alerts/rules/issue/index.spec.tsx

@@ -1,5 +1,6 @@
 import moment from 'moment-timezone';
 import {EnvironmentsFixture} from 'sentry-fixture/environments';
+import {GitHubIntegrationProviderFixture} from 'sentry-fixture/githubIntegrationProvider';
 import {ProjectFixture} from 'sentry-fixture/project';
 import {ProjectAlertRuleFixture} from 'sentry-fixture/projectAlertRule';
 import {ProjectAlertRuleConfigurationFixture} from 'sentry-fixture/projectAlertRuleConfiguration';
@@ -147,6 +148,17 @@ describe('IssueRuleEditor', function () {
       body: [],
     });
     ProjectsStore.loadInitialData([ProjectFixture()]);
+    MockApiClient.addMockResponse({
+      url: `/organizations/org-slug/integrations/?integrationType=messaging`,
+      body: [],
+    });
+    const providerKeys = ['slack', 'discord', 'msteams'];
+    providerKeys.forEach(providerKey => {
+      MockApiClient.addMockResponse({
+        url: `/organizations/org-slug/config/integrations/?provider_key=${providerKey}`,
+        body: {providers: [GitHubIntegrationProviderFixture({key: providerKey})]},
+      });
+    });
   });
 
   afterEach(function () {

+ 19 - 39
static/app/views/alerts/rules/issue/index.tsx

@@ -84,7 +84,6 @@ import PermissionAlert from 'sentry/views/settings/project/permissionAlert';
 import {getProjectOptions} from '../utils';
 
 import RuleNodeList from './ruleNodeList';
-import SetupAlertIntegrationButton from './setupAlertIntegrationButton';
 
 const FREQUENCY_OPTIONS = [
   {value: '5', label: t('5 minutes')},
@@ -1168,9 +1167,6 @@ class IssueRuleEditor extends DeprecatedAsyncView<Props, State> {
     const disabled = loading || !(canCreateAlert || isActiveSuperuser());
     const displayDuplicateError =
       detailedError?.name?.some(str => isExactDuplicateExp.test(str)) ?? false;
-    const hasMessagingIntegrationOnboarding = organization.features.includes(
-      'messaging-integration-onboarding'
-    );
 
     // Note `key` on `<Form>` below is so that on initial load, we show
     // the form with a loading mask on top of it, but force a re-render by using
@@ -1223,21 +1219,13 @@ class IssueRuleEditor extends DeprecatedAsyncView<Props, State> {
             </ContentIndent>
             <SetConditionsListItem>
               <StepHeader>{t('Set conditions')}</StepHeader>{' '}
-              {hasMessagingIntegrationOnboarding ? (
-                <SetupMessagingIntegrationButton
-                  projectId={project.id}
-                  refetchConfigs={this.refetchConfigs}
-                  analyticsParams={{
-                    view: MessagingIntegrationAnalyticsView.ALERT_RULE_CREATION,
-                  }}
-                />
-              ) : (
-                <SetupAlertIntegrationButton
-                  projectSlug={project.slug}
-                  organization={organization}
-                  refetchConfigs={this.refetchConfigs}
-                />
-              )}
+              <SetupMessagingIntegrationButton
+                projectId={project.id}
+                refetchConfigs={this.refetchConfigs}
+                analyticsParams={{
+                  view: MessagingIntegrationAnalyticsView.ALERT_RULE_CREATION,
+                }}
+              />
             </SetConditionsListItem>
             <ContentIndent>
               <ConditionsPanel>
@@ -1443,28 +1431,20 @@ class IssueRuleEditor extends DeprecatedAsyncView<Props, State> {
                               </StyledAlert>
                             )
                           }
-                          {...(hasMessagingIntegrationOnboarding && {
-                            additionalAction: {
-                              label: 'Notify integration\u{2026}',
-                              option: {
-                                label: 'Missing an integration? Click here to refresh',
-                                value: {
-                                  enabled: true,
-                                  id: 'refresh_configs',
-                                  label: 'Refresh Integration List',
-                                },
-                              },
-                              onClick: () => {
-                                trackAnalytics(
-                                  'onboarding.messaging_integration_steps_refreshed',
-                                  {
-                                    organization: this.props.organization,
-                                  }
-                                );
-                                this.refetchConfigs();
+                          additionalAction={{
+                            label: 'Notify integration\u{2026}',
+                            option: {
+                              label: 'Missing an integration? Click here to refresh',
+                              value: {
+                                enabled: true,
+                                id: 'refresh_configs',
+                                label: 'Refresh Integration List',
                               },
                             },
-                          })}
+                            onClick: () => {
+                              this.refetchConfigs();
+                            },
+                          }}
                         />
                         <TestButtonWrapper>
                           <Button

+ 0 - 48
static/app/views/alerts/rules/issue/setupAlertIntegrationButton.spec.tsx

@@ -1,48 +0,0 @@
-import {OrganizationFixture} from 'sentry-fixture/organization';
-import {ProjectFixture} from 'sentry-fixture/project';
-
-import {render} from 'sentry-test/reactTestingLibrary';
-
-import SetupAlertIntegrationButton from 'sentry/views/alerts/rules/issue/setupAlertIntegrationButton';
-
-jest.mock('sentry/actionCreators/modal');
-
-describe('SetupAlertIntegrationButton', function () {
-  const organization = OrganizationFixture();
-  const project = ProjectFixture();
-
-  it('renders slack button if no alert integrations are installed', function () {
-    MockApiClient.addMockResponse({
-      url: `/projects/${organization.slug}/${project.slug}/?expand=hasAlertIntegration`,
-      body: {
-        ...project,
-        hasAlertIntegrationInstalled: false,
-      },
-    });
-    const {container} = render(
-      <SetupAlertIntegrationButton
-        projectSlug={project.slug}
-        organization={organization}
-        refetchConfigs={jest.fn()}
-      />
-    );
-    expect(container).toHaveTextContent('Set Up Slack Now');
-  });
-  it('does not render button if alert integration is installed', function () {
-    MockApiClient.addMockResponse({
-      url: `/projects/${organization.slug}/${project.slug}/?expand=hasAlertIntegration`,
-      body: {
-        ...project,
-        hasAlertIntegrationInstalled: true,
-      },
-    });
-    const {container} = render(
-      <SetupAlertIntegrationButton
-        projectSlug={project.slug}
-        organization={organization}
-        refetchConfigs={jest.fn()}
-      />
-    );
-    expect(container).not.toHaveTextContent('Set Up Slack Now');
-  });
-});

+ 0 - 94
static/app/views/alerts/rules/issue/setupAlertIntegrationButton.tsx

@@ -1,94 +0,0 @@
-import {Button} from 'sentry/components/button';
-import DeprecatedAsyncComponent from 'sentry/components/deprecatedAsyncComponent';
-import {Tooltip} from 'sentry/components/tooltip';
-import {t} from 'sentry/locale';
-import PluginIcon from 'sentry/plugins/components/pluginIcon';
-import ConfigStore from 'sentry/stores/configStore';
-import type {Organization} from 'sentry/types/organization';
-import type {Project} from 'sentry/types/project';
-import {trackAnalytics} from 'sentry/utils/analytics';
-
-type Props = DeprecatedAsyncComponent['props'] & {
-  organization: Organization;
-  projectSlug: string;
-  refetchConfigs: () => void;
-};
-
-type State = DeprecatedAsyncComponent['state'] & {
-  detailedProject?: Project & {
-    hasAlertIntegrationInstalled: boolean;
-  };
-};
-
-/**
- * This component renders a button to Set up an alert integration (just Slack for now)
- * if the project has no alerting integrations setup already. To be replaced by SetupMessagingIntegrationButton.
- */
-export default class SetupAlertIntegrationButton extends DeprecatedAsyncComponent<
-  Props,
-  State
-> {
-  getEndpoints(): ReturnType<DeprecatedAsyncComponent['getEndpoints']> {
-    const {projectSlug, organization} = this.props;
-    return [
-      [
-        'detailedProject',
-        `/projects/${organization.slug}/${projectSlug}/?expand=hasAlertIntegration`,
-      ],
-    ];
-  }
-
-  renderLoading() {
-    return null;
-  }
-
-  // if there is an error, just show nothing
-  renderError() {
-    return null;
-  }
-
-  renderBody(): React.ReactNode {
-    const {organization} = this.props;
-    const {detailedProject} = this.state;
-
-    // don't render anything if we don't have the project yet or if an alert integration
-    // is installed
-    if (!detailedProject || detailedProject.hasAlertIntegrationInstalled) {
-      return null;
-    }
-
-    const {isSelfHosted} = ConfigStore.getState();
-    // link to docs to set up Slack for self-hosted folks
-    const referrerQuery = '?referrer=issue-alert-builder';
-    const buttonProps = isSelfHosted
-      ? {
-          href: `https://develop.sentry.dev/integrations/slack/${referrerQuery}`,
-        }
-      : {
-          to: `/settings/${organization.slug}/integrations/slack/${referrerQuery}`,
-        };
-
-    const onClickHandler = () => {
-      if (!isSelfHosted) {
-        trackAnalytics('onboarding.slack_setup_clicked', {
-          project_id: detailedProject.id,
-          organization,
-        });
-      }
-    };
-    // TOOD(Steve): need to use the Tooltip component because adding a title to the button
-    // puts the tooltip in the upper left hand corner of the page instead of the button
-    return (
-      <Tooltip title={t('Send Alerts to Slack. Install the integration now.')}>
-        <Button
-          size="sm"
-          icon={<PluginIcon pluginId="slack" size={16} />}
-          onClick={onClickHandler}
-          {...buttonProps}
-        >
-          {t('Set Up Slack Now')}
-        </Button>
-      </Tooltip>
-    );
-  }
-}

+ 1 - 3
static/app/views/alerts/rules/issue/setupMessagingIntegrationButton.spec.tsx

@@ -13,9 +13,7 @@ import SetupMessagingIntegrationButton, {
 jest.mock('sentry/actionCreators/modal');
 
 describe('SetupAlertIntegrationButton', function () {
-  const organization = OrganizationFixture({
-    features: ['messaging-integration-onboarding'],
-  });
+  const organization = OrganizationFixture();
   const project = ProjectFixture();
   const providers = (providerKey: string) => [
     GitHubIntegrationProviderFixture({key: providerKey}),