Browse Source

ref(issues): Convert IssueListActions to FC (#38365)

Malachi Willey 2 years ago
parent
commit
b26cd31509

+ 2 - 2
static/app/stores/selectedGroupStore.tsx

@@ -18,7 +18,7 @@ interface InternalDefinition {
 }
 
 interface SelectedGroupStoreDefinition
-  extends CommonStoreDefinition<Map<string, boolean>>,
+  extends CommonStoreDefinition<Record<string, boolean>>,
     InternalDefinition {
   add(ids: string[]): void;
   allSelected(): boolean;
@@ -55,7 +55,7 @@ const storeConfig: SelectedGroupStoreDefinition = {
   },
 
   getState() {
-    return this.records;
+    return Object.fromEntries(this.records);
   },
 
   onGroupChange(itemIds) {

+ 42 - 54
static/app/views/issueList/actions.spec.jsx

@@ -1,6 +1,5 @@
 import React from 'react';
 
-import {initializeOrg} from 'sentry-test/initializeOrg';
 import {
   fireEvent,
   render,
@@ -14,45 +13,51 @@ import GroupStore from 'sentry/stores/groupStore';
 import SelectedGroupStore from 'sentry/stores/selectedGroupStore';
 import {IssueListActions} from 'sentry/views/issueList/actions';
 
-describe('IssueListActions', function () {
-  let org, defaultProps;
+import {OrganizationContext} from '../organizationContext';
+
+const organization = TestStubs.Organization();
+
+const defaultProps = {
+  allResultsVisible: false,
+  query: '',
+  queryCount: 15,
+  projectId: 'project-slug',
+  selection: {
+    projects: [1],
+    environments: [],
+    datetime: {start: null, end: null, period: null, utc: true},
+  },
+  groupIds: ['1', '2', '3'],
+  onRealtimeChange: jest.fn(),
+  onSelectStatsPeriod: jest.fn(),
+  realtimeActive: false,
+  statsPeriod: '24h',
+};
+
+function WrappedComponent(props) {
+  return (
+    <OrganizationContext.Provider value={organization}>
+      <GlobalModal />
+      <IssueListActions {...defaultProps} {...props} />
+    </OrganizationContext.Provider>
+  );
+}
 
+describe('IssueListActions', function () {
   afterEach(() => {
     jest.restoreAllMocks();
   });
 
   beforeEach(() => {
-    const organization = initializeOrg();
-    org = organization.org;
-
     GroupStore.reset();
     SelectedGroupStore.reset();
     SelectedGroupStore.add(['1', '2', '3']);
-
-    defaultProps = {
-      api: new MockApiClient(),
-      allResultsVisible: false,
-      query: '',
-      queryCount: 15,
-      organization: org,
-      projectId: 'project-slug',
-      selection: {
-        projects: [1],
-        environments: [],
-        datetime: {start: null, end: null, period: null, utc: true},
-      },
-      groupIds: ['1', '2', '3'],
-      onRealtimeChange: jest.fn(),
-      onSelectStatsPeriod: jest.fn(),
-      realtimeActive: false,
-      statsPeriod: '24h',
-    };
   });
 
   describe('Bulk', function () {
     describe('Total results greater than bulk limit', function () {
       it('after checking "Select all" checkbox, displays bulk select message', function () {
-        render(<IssueListActions {...defaultProps} queryCount={1500} />);
+        render(<WrappedComponent queryCount={1500} />);
 
         userEvent.click(screen.getByRole('checkbox'));
 
@@ -60,7 +65,7 @@ describe('IssueListActions', function () {
       });
 
       it('can bulk select', function () {
-        render(<IssueListActions {...defaultProps} queryCount={1500} />);
+        render(<WrappedComponent queryCount={1500} />);
 
         userEvent.click(screen.getByRole('checkbox'));
         userEvent.click(screen.getByTestId('issue-list-select-all-notice-link'));
@@ -74,12 +79,7 @@ describe('IssueListActions', function () {
           method: 'PUT',
         });
 
-        render(
-          <React.Fragment>
-            <GlobalModal />
-            <IssueListActions {...defaultProps} queryCount={1500} />
-          </React.Fragment>
-        );
+        render(<WrappedComponent queryCount={1500} />);
         userEvent.click(screen.getByRole('checkbox'));
 
         userEvent.click(screen.getByTestId('issue-list-select-all-notice-link'));
@@ -104,7 +104,7 @@ describe('IssueListActions', function () {
 
     describe('Total results less than bulk limit', function () {
       it('after checking "Select all" checkbox, displays bulk select message', function () {
-        render(<IssueListActions {...defaultProps} queryCount={15} />);
+        render(<WrappedComponent queryCount={15} />);
 
         userEvent.click(screen.getByRole('checkbox'));
 
@@ -112,7 +112,7 @@ describe('IssueListActions', function () {
       });
 
       it('can bulk select', function () {
-        render(<IssueListActions {...defaultProps} queryCount={15} />);
+        render(<WrappedComponent queryCount={15} />);
 
         userEvent.click(screen.getByRole('checkbox'));
 
@@ -127,12 +127,7 @@ describe('IssueListActions', function () {
           method: 'PUT',
         });
 
-        render(
-          <React.Fragment>
-            <GlobalModal />
-            <IssueListActions {...defaultProps} queryCount={15} />
-          </React.Fragment>
-        );
+        render(<WrappedComponent queryCount={15} />);
 
         userEvent.click(screen.getByRole('checkbox'));
 
@@ -167,9 +162,7 @@ describe('IssueListActions', function () {
 
         jest.spyOn(SelectedGroupStore, 'getSelectedIds').mockReturnValue(new Set(['1']));
 
-        render(
-          <IssueListActions {...defaultProps} groupIds={['1', '2', '3', '6', '9']} />
-        );
+        render(<WrappedComponent groupIds={['1', '2', '3', '6', '9']} />);
 
         const resolveButton = screen.getByRole('button', {name: 'Resolve'});
         expect(resolveButton).toBeEnabled();
@@ -194,12 +187,7 @@ describe('IssueListActions', function () {
         });
         jest.spyOn(SelectedGroupStore, 'getSelectedIds').mockReturnValue(new Set(['1']));
 
-        render(
-          <React.Fragment>
-            <GlobalModal />
-            <IssueListActions {...defaultProps} />
-          </React.Fragment>
-        );
+        render(<WrappedComponent {...defaultProps} />);
 
         userEvent.click(screen.getByRole('button', {name: 'Ignore options'}));
         fireEvent.click(screen.getByText(/Until this affects an additional/));
@@ -249,7 +237,7 @@ describe('IssueListActions', function () {
       }
     });
 
-    render(<IssueListActions {...defaultProps} />);
+    render(<WrappedComponent />);
 
     // Can resolve but not merge issues from multiple projects
     expect(screen.getByRole('button', {name: 'Resolve'})).toBeEnabled();
@@ -274,7 +262,7 @@ describe('IssueListActions', function () {
         });
       });
 
-      render(<IssueListActions {...defaultProps} onMarkReviewed={mockOnMarkReviewed} />);
+      render(<WrappedComponent onMarkReviewed={mockOnMarkReviewed} />);
 
       const reviewButton = screen.getByRole('button', {name: 'Mark Reviewed'});
       expect(reviewButton).toBeEnabled();
@@ -288,7 +276,7 @@ describe('IssueListActions', function () {
       SelectedGroupStore.toggleSelectAll();
       GroupStore.loadInitialData([TestStubs.Group({id: '1', inbox: null})]);
 
-      render(<IssueListActions {...defaultProps} />);
+      render(<WrappedComponent {...defaultProps} />);
 
       expect(screen.getByRole('button', {name: 'Mark Reviewed'})).toBeDisabled();
     });
@@ -297,7 +285,7 @@ describe('IssueListActions', function () {
   describe('sort', function () {
     it('calls onSortChange with new sort value', function () {
       const mockOnSortChange = jest.fn();
-      render(<IssueListActions {...defaultProps} onSortChange={mockOnSortChange} />);
+      render(<WrappedComponent onSortChange={mockOnSortChange} />);
 
       userEvent.click(screen.getByRole('button', {name: 'Last Seen'}));
 

+ 213 - 252
static/app/views/issueList/actions/index.tsx

@@ -1,34 +1,32 @@
-import {Component, Fragment} from 'react';
+import {Fragment, useEffect, useState} from 'react';
 import styled from '@emotion/styled';
 import uniq from 'lodash/uniq';
 
 import {bulkDelete, bulkUpdate, mergeGroups} from 'sentry/actionCreators/group';
 import {addLoadingMessage, clearIndicators} from 'sentry/actionCreators/indicator';
-import {Client} from 'sentry/api';
 import Alert from 'sentry/components/alert';
 import Checkbox from 'sentry/components/checkbox';
 import {t, tct, tn} from 'sentry/locale';
 import GroupStore from 'sentry/stores/groupStore';
 import SelectedGroupStore from 'sentry/stores/selectedGroupStore';
+import {useLegacyStore} from 'sentry/stores/useLegacyStore';
 import space from 'sentry/styles/space';
-import {Group, Organization, PageFilters} from 'sentry/types';
-import {callIfFunction} from 'sentry/utils/callIfFunction';
-import withApi from 'sentry/utils/withApi';
+import {Group, PageFilters} from 'sentry/types';
+import useApi from 'sentry/utils/useApi';
+import useOrganization from 'sentry/utils/useOrganization';
 
 import ActionSet from './actionSet';
 import Headers from './headers';
 import {BULK_LIMIT, BULK_LIMIT_STR, ConfirmAction} from './utils';
 
-type Props = {
+type IssueListActionsProps = {
   allResultsVisible: boolean;
-  api: Client;
   displayCount: React.ReactNode;
   displayReprocessingActions: boolean;
   groupIds: string[];
   onDelete: () => void;
   onSelectStatsPeriod: (period: string) => void;
   onSortChange: (sort: string) => void;
-  organization: Organization;
   query: string;
   queryCount: number;
   selection: PageFilters;
@@ -38,96 +36,91 @@ type Props = {
   onMarkReviewed?: (itemIds: string[]) => void;
 };
 
-type State = {
-  allInQuerySelected: boolean;
-  anySelected: boolean;
-  multiSelected: boolean;
-  pageSelected: boolean;
-  selectedIds: Set<string>;
-  selectedProjectSlug?: string;
-};
-
-class IssueListActions extends Component<Props, State> {
-  state: State = {
-    anySelected: false,
-    multiSelected: false, // more than one selected
-    pageSelected: false, // all on current page selected (e.g. 25)
-    allInQuerySelected: false, // all in current search query selected (e.g. 1000+)
-    selectedIds: new Set(),
-  };
-
-  componentDidMount() {
-    this.handleSelectedGroupChange();
-  }
-
-  componentWillUnmount() {
-    callIfFunction(this.listener);
-  }
-
-  listener = SelectedGroupStore.listen(() => this.handleSelectedGroupChange(), undefined);
-
-  actionSelectedGroups(callback: (itemIds: string[] | undefined) => void) {
-    let selectedIds: string[] | undefined;
-
-    if (this.state.allInQuerySelected) {
-      selectedIds = undefined; // undefined means "all"
-    } else {
-      const itemIdSet = SelectedGroupStore.getSelectedIds();
-      selectedIds = this.props.groupIds.filter(itemId => itemIdSet.has(itemId));
-    }
+function IssueListActions({
+  allResultsVisible,
+  displayReprocessingActions,
+  groupIds,
+  onActionTaken,
+  onDelete,
+  onMarkReviewed,
+  onSelectStatsPeriod,
+  onSortChange,
+  queryCount,
+  query,
+  selection,
+  sort,
+  statsPeriod,
+}: IssueListActionsProps) {
+  const api = useApi();
+  const organization = useOrganization();
+  const {
+    pageSelected,
+    multiSelected,
+    anySelected,
+    allInQuerySelected,
+    selectedIdsSet,
+    selectedProjectSlug,
+    setAllInQuerySelected,
+  } = useSelectedGroupsState();
+
+  const numIssues = selectedIdsSet.size;
+
+  function actionSelectedGroups(callback: (itemIds: string[] | undefined) => void) {
+    const selectedIds = allInQuerySelected
+      ? undefined // undefined means "all"
+      : groupIds.filter(itemId => selectedIdsSet.has(itemId));
 
     callback(selectedIds);
 
-    this.deselectAll();
-  }
-
-  deselectAll() {
     SelectedGroupStore.deselectAll();
-    this.setState({allInQuerySelected: false});
   }
 
-  // Handler for when `SelectedGroupStore` changes
-  handleSelectedGroupChange() {
-    const selected = SelectedGroupStore.getSelectedIds();
-    const projects = [...selected]
-      .map(id => GroupStore.get(id))
-      .filter((group): group is Group => !!(group && group.project))
-      .map(group => group.project.slug);
-
-    const uniqProjects = uniq(projects);
-
-    // we only want selectedProjectSlug set if there is 1 project
-    // more or fewer should result in a null so that the action toolbar
-    // can behave correctly.
-    const selectedProjectSlug = uniqProjects.length === 1 ? uniqProjects[0] : undefined;
-
-    this.setState({
-      pageSelected: SelectedGroupStore.allSelected(),
-      multiSelected: SelectedGroupStore.multiSelected(),
-      anySelected: SelectedGroupStore.anySelected(),
-      allInQuerySelected: false, // any change resets
-      selectedIds: SelectedGroupStore.getSelectedIds(),
-      selectedProjectSlug,
+  function handleDelete() {
+    const orgId = organization.slug;
+
+    actionSelectedGroups(itemIds => {
+      bulkDelete(
+        api,
+        {
+          orgId,
+          itemIds,
+          query,
+          project: selection.projects,
+          environment: selection.environments,
+          ...selection.datetime,
+        },
+        {
+          complete: () => {
+            onDelete();
+          },
+        }
+      );
     });
   }
 
-  handleSelectStatsPeriod = (period: string) => {
-    return this.props.onSelectStatsPeriod(period);
-  };
-
-  handleApplyToAll = () => {
-    this.setState({allInQuerySelected: true});
-  };
+  function handleMerge() {
+    actionSelectedGroups(itemIds => {
+      mergeGroups(
+        api,
+        {
+          orgId: organization.slug,
+          itemIds,
+          query,
+          project: selection.projects,
+          environment: selection.environments,
+          ...selection.datetime,
+        },
+        {}
+      );
+    });
+  }
 
-  handleUpdate = (data?: any) => {
-    const {selection, api, organization, query, onMarkReviewed, onActionTaken} =
-      this.props;
-    const orgId = organization.slug;
+  function handleUpdate(data?: any) {
     const hasIssueListRemovalAction = organization.features.includes(
       'issue-list-removal-action'
     );
 
-    this.actionSelectedGroups(itemIds => {
+    actionSelectedGroups(itemIds => {
       // TODO(Kelly): remove once issue-list-removal-action feature is stable
       if (!hasIssueListRemovalAction) {
         addLoadingMessage(t('Saving changes\u2026'));
@@ -150,7 +143,7 @@ class IssueListActions extends Component<Props, State> {
       bulkUpdate(
         api,
         {
-          orgId,
+          orgId: organization.slug,
           itemIds,
           data,
           query,
@@ -167,178 +160,146 @@ class IssueListActions extends Component<Props, State> {
         }
       );
     });
-  };
-
-  handleDelete = () => {
-    const {selection, api, organization, query, onDelete} = this.props;
-    const orgId = organization.slug;
-
-    this.actionSelectedGroups(itemIds => {
-      bulkDelete(
-        api,
-        {
-          orgId,
-          itemIds,
-          query,
-          project: selection.projects,
-          environment: selection.environments,
-          ...selection.datetime,
-        },
-        {
-          complete: () => {
-            onDelete();
-          },
-        }
-      );
-    });
-  };
-
-  handleMerge = () => {
-    const {selection, api, organization, query} = this.props;
-    const orgId = organization.slug;
-
-    this.actionSelectedGroups(itemIds => {
-      mergeGroups(
-        api,
-        {
-          orgId,
-          itemIds,
-          query,
-          project: selection.projects,
-          environment: selection.environments,
-          ...selection.datetime,
-        },
-        {}
-      );
-    });
-  };
-
-  handleSelectAll() {
-    SelectedGroupStore.toggleSelectAll();
   }
 
-  shouldConfirm = (action: ConfirmAction) => {
-    const selectedItems = SelectedGroupStore.getSelectedIds();
-
-    switch (action) {
-      case ConfirmAction.RESOLVE:
-      case ConfirmAction.UNRESOLVE:
-      case ConfirmAction.IGNORE:
-      case ConfirmAction.UNBOOKMARK: {
-        const {pageSelected} = this.state;
-        return pageSelected && selectedItems.size > 1;
-      }
-      case ConfirmAction.BOOKMARK:
-        return selectedItems.size > 1;
-      case ConfirmAction.MERGE:
-      case ConfirmAction.DELETE:
-      default:
-        return true; // By default, should confirm ...
-    }
-  };
-  render() {
-    const {
-      allResultsVisible,
-      queryCount,
-      query,
-      statsPeriod,
-      selection,
-      organization,
-      displayReprocessingActions,
-    } = this.props;
-
-    const {
-      allInQuerySelected,
-      anySelected,
-      pageSelected,
-      selectedIds: issues,
-      multiSelected,
-      selectedProjectSlug,
-    } = this.state;
-
-    const numIssues = issues.size;
-
-    return (
-      <Sticky>
-        <StyledFlex>
-          <ActionsCheckbox isReprocessingQuery={displayReprocessingActions}>
-            <Checkbox
-              onChange={this.handleSelectAll}
-              checked={pageSelected || (anySelected ? 'indeterminate' : false)}
-              disabled={displayReprocessingActions}
-            />
-          </ActionsCheckbox>
-          {!displayReprocessingActions && (
-            <ActionSet
-              sort={this.props.sort}
-              onSortChange={this.props.onSortChange}
-              orgSlug={organization.slug}
-              queryCount={queryCount}
-              query={query}
-              issues={issues}
-              allInQuerySelected={allInQuerySelected}
-              anySelected={anySelected}
-              multiSelected={multiSelected}
-              selectedProjectSlug={selectedProjectSlug}
-              onShouldConfirm={this.shouldConfirm}
-              onDelete={this.handleDelete}
-              onMerge={this.handleMerge}
-              onUpdate={this.handleUpdate}
-            />
-          )}
-          <Headers
-            onSelectStatsPeriod={this.handleSelectStatsPeriod}
+  return (
+    <Sticky>
+      <StyledFlex>
+        <ActionsCheckbox isReprocessingQuery={displayReprocessingActions}>
+          <Checkbox
+            onChange={() => SelectedGroupStore.toggleSelectAll()}
+            checked={pageSelected || (anySelected ? 'indeterminate' : false)}
+            disabled={displayReprocessingActions}
+          />
+        </ActionsCheckbox>
+        {!displayReprocessingActions && (
+          <ActionSet
+            sort={sort}
+            onSortChange={onSortChange}
+            orgSlug={organization.slug}
+            queryCount={queryCount}
+            query={query}
+            issues={selectedIdsSet}
+            allInQuerySelected={allInQuerySelected}
             anySelected={anySelected}
-            selection={selection}
-            statsPeriod={statsPeriod}
-            isReprocessingQuery={displayReprocessingActions}
+            multiSelected={multiSelected}
+            selectedProjectSlug={selectedProjectSlug}
+            onShouldConfirm={action =>
+              shouldConfirm(action, {pageSelected, selectedIdsSet})
+            }
+            onDelete={handleDelete}
+            onMerge={handleMerge}
+            onUpdate={handleUpdate}
           />
-        </StyledFlex>
-        {!allResultsVisible && pageSelected && (
-          <Alert type="warning" system>
-            <SelectAllNotice data-test-id="issue-list-select-all-notice">
-              {allInQuerySelected ? (
-                queryCount >= BULK_LIMIT ? (
-                  tct(
-                    'Selected up to the first [count] issues that match this search query.',
-                    {
-                      count: BULK_LIMIT_STR,
-                    }
-                  )
-                ) : (
-                  tct('Selected all [count] issues that match this search query.', {
-                    count: queryCount,
-                  })
+        )}
+        <Headers
+          onSelectStatsPeriod={onSelectStatsPeriod}
+          anySelected={anySelected}
+          selection={selection}
+          statsPeriod={statsPeriod}
+          isReprocessingQuery={displayReprocessingActions}
+        />
+      </StyledFlex>
+      {!allResultsVisible && pageSelected && (
+        <Alert type="warning" system>
+          <SelectAllNotice data-test-id="issue-list-select-all-notice">
+            {allInQuerySelected ? (
+              queryCount >= BULK_LIMIT ? (
+                tct(
+                  'Selected up to the first [count] issues that match this search query.',
+                  {
+                    count: BULK_LIMIT_STR,
+                  }
                 )
               ) : (
-                <Fragment>
-                  {tn(
-                    '%s issue on this page selected.',
-                    '%s issues on this page selected.',
-                    numIssues
-                  )}
-                  <SelectAllLink
-                    onClick={this.handleApplyToAll}
-                    data-test-id="issue-list-select-all-notice-link"
-                  >
-                    {queryCount >= BULK_LIMIT
-                      ? tct(
-                          'Select the first [count] issues that match this search query.',
-                          {
-                            count: BULK_LIMIT_STR,
-                          }
-                        )
-                      : tct('Select all [count] issues that match this search query.', {
-                          count: queryCount,
-                        })}
-                  </SelectAllLink>
-                </Fragment>
-              )}
-            </SelectAllNotice>
-          </Alert>
-        )}
-      </Sticky>
-    );
+                tct('Selected all [count] issues that match this search query.', {
+                  count: queryCount,
+                })
+              )
+            ) : (
+              <Fragment>
+                {tn(
+                  '%s issue on this page selected.',
+                  '%s issues on this page selected.',
+                  numIssues
+                )}
+                <SelectAllLink
+                  onClick={() => setAllInQuerySelected(true)}
+                  data-test-id="issue-list-select-all-notice-link"
+                >
+                  {queryCount >= BULK_LIMIT
+                    ? tct(
+                        'Select the first [count] issues that match this search query.',
+                        {
+                          count: BULK_LIMIT_STR,
+                        }
+                      )
+                    : tct('Select all [count] issues that match this search query.', {
+                        count: queryCount,
+                      })}
+                </SelectAllLink>
+              </Fragment>
+            )}
+          </SelectAllNotice>
+        </Alert>
+      )}
+    </Sticky>
+  );
+}
+
+function useSelectedGroupsState() {
+  const [allInQuerySelected, setAllInQuerySelected] = useState(false);
+  const selectedIds = useLegacyStore(SelectedGroupStore);
+
+  const selected = SelectedGroupStore.getSelectedIds();
+  const projects = [...selected]
+    .map(id => GroupStore.get(id))
+    .filter((group): group is Group => !!(group && group.project))
+    .map(group => group.project.slug);
+
+  const uniqProjects = uniq(projects);
+  // we only want selectedProjectSlug set if there is 1 project
+  // more or fewer should result in a null so that the action toolbar
+  // can behave correctly.
+  const selectedProjectSlug = uniqProjects.length === 1 ? uniqProjects[0] : undefined;
+
+  const pageSelected = SelectedGroupStore.allSelected();
+  const multiSelected = SelectedGroupStore.multiSelected();
+  const anySelected = SelectedGroupStore.anySelected();
+  const selectedIdsSet = SelectedGroupStore.getSelectedIds();
+
+  useEffect(() => {
+    setAllInQuerySelected(false);
+  }, [selectedIds]);
+
+  return {
+    pageSelected,
+    multiSelected,
+    anySelected,
+    allInQuerySelected,
+    selectedIdsSet,
+    selectedProjectSlug,
+    setAllInQuerySelected,
+  };
+}
+
+function shouldConfirm(
+  action: ConfirmAction,
+  {pageSelected, selectedIdsSet}: {pageSelected: boolean; selectedIdsSet: Set<string>}
+) {
+  switch (action) {
+    case ConfirmAction.RESOLVE:
+    case ConfirmAction.UNRESOLVE:
+    case ConfirmAction.IGNORE:
+    case ConfirmAction.UNBOOKMARK: {
+      return pageSelected && selectedIdsSet.size > 1;
+    }
+    case ConfirmAction.BOOKMARK:
+      return selectedIdsSet.size > 1;
+    case ConfirmAction.MERGE:
+    case ConfirmAction.DELETE:
+    default:
+      return true; // By default, should confirm ...
   }
 }
 
@@ -388,4 +349,4 @@ const SelectAllLink = styled('a')`
 
 export {IssueListActions};
 
-export default withApi(IssueListActions);
+export default IssueListActions;

+ 5 - 1
static/app/views/issueList/overview.polling.spec.jsx

@@ -6,6 +6,8 @@ import StreamGroup from 'sentry/components/stream/group';
 import TagStore from 'sentry/stores/tagStore';
 import IssueList from 'sentry/views/issueList/overview';
 
+import {OrganizationContext} from '../organizationContext';
+
 // Mock <IssueListSidebar> (need <IssueListActions> to toggling real time polling)
 jest.mock('sentry/views/issueList/sidebar', () => jest.fn(() => null));
 jest.mock('sentry/views/issueList/filters', () => jest.fn(() => null));
@@ -64,7 +66,9 @@ describe('IssueList -> Polling', function () {
     };
 
     wrapper = mountWithTheme(
-      <IssueList {...newRouter} {...defaultProps} {...p} />,
+      <OrganizationContext.Provider value={TestStubs.Organization()}>
+        <IssueList {...newRouter} {...defaultProps} {...p} />
+      </OrganizationContext.Provider>,
       routerContext
     );
 

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

@@ -1263,7 +1263,6 @@ class IssueListOverview extends Component<Props, State> {
 
             <Panel>
               <IssueListActions
-                organization={organization}
                 selection={selection}
                 query={query}
                 queryCount={modifiedQueryCount}