Browse Source

Remove the "Processing Issues" settings page / hint (#73822)

As part of deprecating legacy reprocessing, this completely removes the
"Processing Issues" page from settings, as well as the Processing Issues
Hint from the issues stream.

It leaves other parts of the issues stream untouched, which I believe
are still in-use for "reprocessing2".
Arpad Borsos 8 months ago
parent
commit
7ab0387d10

+ 0 - 12
static/app/actionCreators/processingIssues.tsx

@@ -1,12 +0,0 @@
-import type {Client} from 'sentry/api';
-
-export function fetchProcessingIssues(
-  api: Client,
-  orgId: string,
-  projectIds: string[] | null = null
-) {
-  return api.requestPromise(`/organizations/${orgId}/processingissues/`, {
-    method: 'GET',
-    query: projectIds ? {project: projectIds} : [],
-  });
-}

+ 2 - 3
static/app/components/events/interfaces/crashContent/exception/actionableItemsUtils.tsx

@@ -10,7 +10,7 @@ import {
   NativeProcessingErrors,
   NativeProcessingErrors,
   ProguardProcessingErrors,
   ProguardProcessingErrors,
 } from 'sentry/constants/eventErrors';
 } from 'sentry/constants/eventErrors';
-import {tct} from 'sentry/locale';
+import {t, tct} from 'sentry/locale';
 import type {DebugFile} from 'sentry/types/debugFiles';
 import type {DebugFile} from 'sentry/types/debugFiles';
 import type {Image} from 'sentry/types/debugImage';
 import type {Image} from 'sentry/types/debugImage';
 import type {Event, ExceptionValue, Thread} from 'sentry/types/event';
 import type {Event, ExceptionValue, Thread} from 'sentry/types/event';
@@ -21,7 +21,6 @@ import {trackAnalytics} from 'sentry/utils/analytics';
 import {useApiQuery} from 'sentry/utils/queryClient';
 import {useApiQuery} from 'sentry/utils/queryClient';
 import useOrganization from 'sentry/utils/useOrganization';
 import useOrganization from 'sentry/utils/useOrganization';
 import {semverCompare} from 'sentry/utils/versions/semverCompare';
 import {semverCompare} from 'sentry/utils/versions/semverCompare';
-import {projectProcessingIssuesMessages} from 'sentry/views/settings/project/projectProcessingIssues';
 
 
 const MINIFIED_DATA_JAVA_EVENT_REGEX_MATCH =
 const MINIFIED_DATA_JAVA_EVENT_REGEX_MATCH =
   /^(([\w\$]\.[\w\$]{1,2})|([\w\$]{2}\.[\w\$]\.[\w\$]))(\.|$)/g;
   /^(([\w\$]\.[\w\$]{1,2})|([\w\$]{2}\.[\w\$]\.[\w\$]))(\.|$)/g;
@@ -243,7 +242,7 @@ export const useFetchProguardMappingFiles = ({
       return [
       return [
         {
         {
           type: 'proguard_missing_mapping',
           type: 'proguard_missing_mapping',
-          message: projectProcessingIssuesMessages.proguard_missing_mapping,
+          message: t('A proguard mapping file was missing.'),
           data: {mapping_uuid: proGuardImageUuid},
           data: {mapping_uuid: proGuardImageUuid},
         },
         },
       ];
       ];

+ 0 - 121
static/app/components/stream/processingIssueHint.spec.tsx

@@ -1,121 +0,0 @@
-import {render, screen} from 'sentry-test/reactTestingLibrary';
-
-import ProcessingIssueHint from 'sentry/components/stream/processingIssueHint';
-
-describe('ProcessingIssueHint', function () {
-  let issue, container;
-  const orgId = 'test-org';
-  const projectId = 'test-project';
-
-  beforeEach(() => {
-    issue = {
-      hasIssues: false,
-      hasMoreResolveableIssues: false,
-      issuesProcessing: 0,
-      lastSeen: '2019-01-16T15:38:38Z',
-      numIssues: 0,
-      resolveableIssues: 0,
-      signedLink: null,
-    };
-  });
-
-  function renderComponent(issueData, showProject = false) {
-    const result = render(
-      <ProcessingIssueHint
-        issue={issueData}
-        orgId={orgId}
-        projectId={projectId}
-        showProject={showProject}
-      />
-    );
-    container = result.container;
-  }
-
-  describe('numIssues state', function () {
-    beforeEach(() => {
-      issue.numIssues = 9;
-    });
-
-    it('displays a button', function () {
-      renderComponent(issue);
-      const button = screen.getByRole('button');
-      expect(button).toBeInTheDocument();
-      expect(button).toHaveAttribute(
-        'href',
-        `/settings/${orgId}/projects/${projectId}/processing-issues/`
-      );
-    });
-
-    it('displays an icon', function () {
-      renderComponent(issue);
-      const icon = container.querySelector('svg');
-      expect(icon).toBeInTheDocument();
-    });
-
-    it('displays text', function () {
-      renderComponent(issue);
-      expect(screen.getByText(/issues blocking/)).toBeInTheDocument();
-    });
-  });
-
-  describe('issuesProcessing state', function () {
-    beforeEach(() => {
-      issue.issuesProcessing = 9;
-    });
-
-    it('does not display a button', function () {
-      renderComponent(issue);
-      expect(screen.queryByRole('button')).not.toBeInTheDocument();
-    });
-
-    it('displays an icon', function () {
-      renderComponent(issue);
-      const icon = container.querySelector('svg');
-      expect(icon).toBeInTheDocument();
-    });
-
-    it('displays text', function () {
-      renderComponent(issue);
-      expect(screen.getByText(/Reprocessing/)).toBeInTheDocument();
-    });
-  });
-
-  describe('resolvableIssues state', function () {
-    beforeEach(() => {
-      issue.resolveableIssues = 9;
-    });
-
-    it('displays a button', function () {
-      renderComponent(issue);
-      const button = screen.getByRole('button');
-      expect(button).toBeInTheDocument();
-      expect(button).toHaveAttribute(
-        'href',
-        `/settings/${orgId}/projects/${projectId}/processing-issues/`
-      );
-    });
-
-    it('displays an icon', function () {
-      renderComponent(issue);
-      const icon = container.querySelector('svg');
-      expect(icon).toBeInTheDocument();
-    });
-
-    it('displays text', function () {
-      renderComponent(issue);
-      expect(
-        screen.getByText('There are 9 events pending reprocessing.')
-      ).toBeInTheDocument();
-    });
-  });
-
-  describe('showProject state', function () {
-    beforeEach(() => {
-      issue.numIssues = 9;
-    });
-    it('displays the project slug', function () {
-      renderComponent(issue, true);
-      expect(screen.getByText(projectId)).toBeInTheDocument();
-    });
-  });
-});

+ 0 - 101
static/app/components/stream/processingIssueHint.tsx

@@ -1,101 +0,0 @@
-import {Fragment} from 'react';
-import styled from '@emotion/styled';
-
-import type {AlertProps} from 'sentry/components/alert';
-import {Alert} from 'sentry/components/alert';
-import {Button} from 'sentry/components/button';
-import TimeSince from 'sentry/components/timeSince';
-import {t, tct, tn} from 'sentry/locale';
-import {space} from 'sentry/styles/space';
-import type {ProcessingIssue} from 'sentry/types';
-
-type Props = {
-  issue: ProcessingIssue;
-  orgId: string;
-  projectId: string;
-  showProject: boolean;
-};
-
-function ProcessingIssueHint({orgId, projectId, issue, showProject}: Props) {
-  const link = `/settings/${orgId}/projects/${projectId}/processing-issues/`;
-  let showButton = false;
-  let text = '';
-  let lastEvent: React.ReactNode = null;
-  let alertType: AlertProps['type'] = 'error';
-
-  let project: React.ReactNode = null;
-  if (showProject) {
-    project = (
-      <Fragment>
-        <strong>{projectId}</strong> &mdash;{' '}
-      </Fragment>
-    );
-  }
-
-  if (issue.numIssues > 0) {
-    text = tn(
-      'There is %s issue blocking event processing',
-      'There are %s issues blocking event processing',
-      issue.numIssues
-    );
-    lastEvent = (
-      <Fragment>
-        (
-        {tct('last event from [ago]', {
-          ago: <TimeSince date={issue.lastSeen} />,
-        })}
-        )
-      </Fragment>
-    );
-    alertType = 'error';
-    showButton = true;
-  } else if (issue.issuesProcessing > 0) {
-    alertType = 'info';
-    text = tn(
-      'Reprocessing %s event …',
-      'Reprocessing %s events …',
-      issue.issuesProcessing
-    );
-  } else if (issue.resolveableIssues > 0) {
-    alertType = 'warning';
-    text = tn(
-      'There is %s event pending reprocessing.',
-      'There are %s events pending reprocessing.',
-      issue.resolveableIssues
-    );
-    showButton = true;
-  } else {
-    /* we should not go here but what do we know */
-    return null;
-  }
-
-  return (
-    <StyledAlert
-      type={alertType}
-      showIcon
-      trailingItems={
-        showButton && (
-          <StyledButton size="xs" to={link}>
-            {t('Show details')}
-          </StyledButton>
-        )
-      }
-    >
-      {project} <strong>{text}</strong> {lastEvent}
-    </StyledAlert>
-  );
-}
-
-export default ProcessingIssueHint;
-
-const StyledAlert = styled(Alert)`
-  border-width: 1px 0;
-  border-radius: 0;
-  margin: 0;
-  font-size: ${p => p.theme.fontSizeMedium};
-`;
-
-const StyledButton = styled(Button)`
-  white-space: nowrap;
-  margin-left: ${space(1)};
-`;

+ 0 - 64
static/app/components/stream/processingIssueList.spec.tsx

@@ -1,64 +0,0 @@
-import {OrganizationFixture} from 'sentry-fixture/organization';
-
-import {render, screen} from 'sentry-test/reactTestingLibrary';
-
-import ProcessingIssueList from 'sentry/components/stream/processingIssueList';
-
-describe('ProcessingIssueList', function () {
-  let projects, organization, fetchIssueRequest;
-
-  beforeEach(function () {
-    fetchIssueRequest = MockApiClient.addMockResponse({
-      url: '/organizations/org-slug/processingissues/',
-      method: 'GET',
-      body: [
-        {
-          project: 'test-project',
-          numIssues: 1,
-          hasIssues: true,
-          lastSeen: '2019-01-16T15:39:11.081Z',
-        },
-        {
-          project: 'other-project',
-          numIssues: 1,
-          hasIssues: true,
-          lastSeen: '2019-01-16T15:39:11.081Z',
-        },
-      ],
-    });
-    organization = OrganizationFixture();
-    projects = [1, 2];
-  });
-
-  describe('componentDidMount', function () {
-    it('fetches issues', async function () {
-      render(<ProcessingIssueList organization={organization} projectIds={projects} />);
-      await screen.findAllByText('Show details');
-
-      expect(fetchIssueRequest).toHaveBeenCalled();
-    });
-  });
-
-  describe('render', function () {
-    it('renders multiple issues', async function () {
-      render(<ProcessingIssueList organization={organization} projectIds={projects} />);
-      const items = await screen.findAllByText(/There is 1 issue blocking/);
-      expect(items).toHaveLength(2);
-    });
-
-    it('forwards the showProject prop', async function () {
-      render(
-        <ProcessingIssueList
-          organization={organization}
-          showProject
-          projectIds={projects}
-        />
-      );
-      const projectText = await screen.findByText(/test-project/);
-      expect(projectText).toBeInTheDocument();
-
-      const otherProject = screen.getByText(/other-project/);
-      expect(otherProject).toBeInTheDocument();
-    });
-  });
-});

+ 0 - 87
static/app/components/stream/processingIssueList.tsx

@@ -1,87 +0,0 @@
-import {Component, Fragment} from 'react';
-import isEqual from 'lodash/isEqual';
-
-import {fetchProcessingIssues} from 'sentry/actionCreators/processingIssues';
-import {Client} from 'sentry/api';
-import ProcessingIssueHint from 'sentry/components/stream/processingIssueHint';
-import type {Organization, ProcessingIssue} from 'sentry/types';
-
-const defaultProps = {
-  showProject: false,
-};
-
-type Props = {
-  organization: Organization;
-  projectIds: string[];
-} & typeof defaultProps;
-
-type State = {
-  issues: ProcessingIssue[];
-  loading: boolean;
-};
-
-class ProcessingIssueList extends Component<Props, State> {
-  static defaultProps = defaultProps;
-
-  state: State = {
-    loading: true,
-    issues: [],
-  };
-
-  componentDidMount() {
-    this.fetchIssues();
-  }
-
-  componentDidUpdate(prevProps: Props) {
-    if (!isEqual(prevProps.projectIds, this.props.projectIds)) {
-      this.fetchIssues();
-    }
-  }
-
-  componentWillUnmount() {
-    this.api.clear();
-  }
-
-  api = new Client();
-
-  fetchIssues() {
-    const {organization, projectIds} = this.props;
-    const promise = fetchProcessingIssues(this.api, organization.slug, projectIds);
-
-    promise.then(
-      (data?: ProcessingIssue[]) => {
-        const hasIssues = data?.some(
-          p => p.hasIssues || p.resolveableIssues > 0 || p.issuesProcessing > 0
-        );
-
-        if (data && hasIssues) {
-          this.setState({issues: data});
-        }
-      },
-      () => {
-        // this is okay. it's just a ui hint
-      }
-    );
-  }
-
-  render() {
-    const {issues} = this.state;
-    const {organization, showProject} = this.props;
-
-    return (
-      <Fragment>
-        {issues.map((p, idx) => (
-          <ProcessingIssueHint
-            key={idx}
-            issue={p}
-            projectId={p.project}
-            orgId={organization.slug}
-            showProject={showProject}
-          />
-        ))}
-      </Fragment>
-    );
-  }
-}
-
-export default ProcessingIssueList;

+ 0 - 36
static/app/data/forms/processingIssues.tsx

@@ -1,36 +0,0 @@
-// Export route to make these forms searchable by label/help
-import type {JsonFormObject} from 'sentry/components/forms/types';
-import {t} from 'sentry/locale';
-
-export const route = '/settings/:orgId/projects/:projectId/processing-issues/';
-
-const formGroups: JsonFormObject[] = [
-  {
-    // Form "section"/"panel"
-    title: 'Settings',
-    fields: [
-      {
-        name: 'sentry:reprocessing_active',
-        type: 'boolean',
-        label: t('Reprocessing active'),
-        disabled: ({access}) => !access.has('project:write'),
-        disabledReason: t('Only admins may change reprocessing settings'),
-        help: t(`If reprocessing is enabled, Events with fixable issues will be
-                held back until you resolve them. Processing issues will then
-                show up in the list above with hints how to fix them.
-                If reprocessing is disabled, Events with unresolved issues will
-                also show up in the stream.
-                `),
-        saveOnBlur: false,
-        saveMessage: ({value}) =>
-          value
-            ? t('Reprocessing applies to future events only.')
-            : t(`All events with errors will be flushed into your issues stream.
-                Beware that this process may take some time and cannot be undone.`),
-        getData: form => ({options: form}),
-      },
-    ],
-  },
-];
-
-export default formGroups;

+ 0 - 11
static/app/routes.tsx

@@ -595,13 +595,6 @@ function buildRoutes() {
         </Route>
         </Route>
         <Redirect from=":name/" to="release-bundles/:name/" />
         <Redirect from=":name/" to="release-bundles/:name/" />
       </Route>
       </Route>
-      <Route
-        path="processing-issues/"
-        name={t('Processing Issues')}
-        component={make(
-          () => import('sentry/views/settings/project/projectProcessingIssues')
-        )}
-      />
       <Route
       <Route
         path="filters/"
         path="filters/"
         name={t('Inbound Filters')}
         name={t('Inbound Filters')}
@@ -2182,10 +2175,6 @@ function buildRoutes() {
           from="debug-symbols/"
           from="debug-symbols/"
           to="/settings/:orgId/projects/:projectId/debug-symbols/"
           to="/settings/:orgId/projects/:projectId/debug-symbols/"
         />
         />
-        <Redirect
-          from="processing-issues/"
-          to="/settings/:orgId/projects/:projectId/processing-issues/"
-        />
         <Redirect from="filters/" to="/settings/:orgId/projects/:projectId/filters/" />
         <Redirect from="filters/" to="/settings/:orgId/projects/:projectId/filters/" />
         <Redirect from="hooks/" to="/settings/:orgId/projects/:projectId/hooks/" />
         <Redirect from="hooks/" to="/settings/:orgId/projects/:projectId/hooks/" />
         <Redirect from="keys/" to="/settings/:orgId/projects/:projectId/keys/" />
         <Redirect from="keys/" to="/settings/:orgId/projects/:projectId/keys/" />

+ 0 - 30
static/app/types/group.tsx

@@ -855,36 +855,6 @@ export interface GroupTombstoneHelper extends GroupTombstone {
   isTombstone: true;
   isTombstone: true;
 }
 }
 
 
-export type ProcessingIssueItem = {
-  checksum: string;
-  data: {
-    // TODO(ts) This type is likely incomplete, but this is what
-    // project processing issues settings uses.
-    _scope: string;
-    image_arch: string;
-    image_path: string;
-    image_uuid: string;
-    dist?: string;
-    release?: string;
-  };
-  id: string;
-  lastSeen: string;
-  numEvents: number;
-  type: string;
-};
-
-export type ProcessingIssue = {
-  hasIssues: boolean;
-  hasMoreResolveableIssues: boolean;
-  issuesProcessing: number;
-  lastSeen: string;
-  numIssues: number;
-  project: string;
-  resolveableIssues: number;
-  signedLink: string;
-  issues?: ProcessingIssueItem[];
-};
-
 /**
 /**
  * Datascrubbing
  * Datascrubbing
  */
  */

+ 1 - 7
static/app/views/issueList/overview.tsx

@@ -24,7 +24,6 @@ import Pagination from 'sentry/components/pagination';
 import Panel from 'sentry/components/panels/panel';
 import Panel from 'sentry/components/panels/panel';
 import PanelBody from 'sentry/components/panels/panelBody';
 import PanelBody from 'sentry/components/panels/panelBody';
 import QueryCount from 'sentry/components/queryCount';
 import QueryCount from 'sentry/components/queryCount';
-import ProcessingIssueList from 'sentry/components/stream/processingIssueList';
 import {DEFAULT_QUERY, DEFAULT_STATS_PERIOD} from 'sentry/constants';
 import {DEFAULT_QUERY, DEFAULT_STATS_PERIOD} from 'sentry/constants';
 import {t, tct} from 'sentry/locale';
 import {t, tct} from 'sentry/locale';
 import GroupStore from 'sentry/stores/groupStore';
 import GroupStore from 'sentry/stores/groupStore';
@@ -1208,8 +1207,8 @@ class IssueListOverview extends Component<Props, State> {
     const query = this.getQuery();
     const query = this.getQuery();
 
 
     const modifiedQueryCount = Math.max(queryCount, 0);
     const modifiedQueryCount = Math.max(queryCount, 0);
-    const projectIds = selection?.projects?.map(p => p.toString());
 
 
+    // TODO: these two might still be in use for reprocessing2
     const showReprocessingTab = this.displayReprocessingTab();
     const showReprocessingTab = this.displayReprocessingTab();
     const displayReprocessingActions = this.displayReprocessingLayout(
     const displayReprocessingActions = this.displayReprocessingLayout(
       showReprocessingTab,
       showReprocessingTab,
@@ -1255,11 +1254,6 @@ class IssueListOverview extends Component<Props, State> {
                 />
                 />
               )}
               )}
               <PanelBody>
               <PanelBody>
-                <ProcessingIssueList
-                  organization={organization}
-                  projectIds={projectIds}
-                  showProject
-                />
                 <VisuallyCompleteWithData
                 <VisuallyCompleteWithData
                   hasData={this.state.groupIds.length > 0}
                   hasData={this.state.groupIds.length > 0}
                   id="IssueList-Body"
                   id="IssueList-Body"

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