Browse Source

ref(userFeedback): Use `SegmentedControl` for issue status filter (#44073)

**Before ——**
<img width="880" alt="Screenshot 2023-02-02 at 3 12 16 PM"
src="https://user-images.githubusercontent.com/44172267/216472062-159e6b42-cc72-4e7d-a898-1012ba0844f1.png">

**After ——**
<img width="880" alt="Screenshot 2023-02-02 at 3 12 00 PM"
src="https://user-images.githubusercontent.com/44172267/216472028-30bec2cd-be28-4c3b-ae7e-cf17bea06e34.png">

https://github.com/getsentry/sentry/issues/43865
Vu Luong 2 years ago
parent
commit
311a4b5e19
2 changed files with 45 additions and 20 deletions
  1. 29 10
      static/app/views/userFeedback/index.spec.jsx
  2. 16 10
      static/app/views/userFeedback/index.tsx

+ 29 - 10
static/app/views/userFeedback/index.spec.jsx

@@ -1,11 +1,11 @@
 import {initializeOrg} from 'sentry-test/initializeOrg';
-import {render, screen} from 'sentry-test/reactTestingLibrary';
+import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
 
 import ProjectsStore from 'sentry/stores/projectsStore';
 import UserFeedback from 'sentry/views/userFeedback';
 
 describe('UserFeedback', function () {
-  const {organization, routerContext} = initializeOrg();
+  const {organization, router, routerContext} = initializeOrg();
   const pageLinks =
     '<https://sentry.io/api/0/organizations/sentry/user-feedback/?statsPeriod=14d&cursor=0:0:1>; rel="previous"; results="false"; cursor="0:0:1", ' +
     '<https://sentry.io/api/0/organizations/sentry/user-feedback/?statsPeriod=14d&cursor=0:100:0>; rel="next"; results="true"; cursor="0:100:0"';
@@ -106,10 +106,34 @@ describe('UserFeedback', function () {
     render(<UserFeedback {...params} />, {context: routerContext});
 
     expect(screen.getByTestId('user-feedback-empty')).toBeInTheDocument();
+  });
 
-    expect(screen.getByRole('button', {name: 'All Issues'})).toHaveAttribute(
-      'href',
-      'sentry?project=112&status='
+  it('renders issue status filter', function () {
+    const params = {
+      organization: TestStubs.Organization({
+        projects: [TestStubs.Project({isMember: true})],
+      }),
+      location: router.location,
+      params: {
+        orgId: organization.slug,
+      },
+      router,
+    };
+    render(<UserFeedback {...params} />, {context: routerContext});
+
+    // "Unresolved"  is selected by default
+    const unresolved = screen.getByRole('radio', {name: 'Unresolved'});
+    expect(unresolved).toBeInTheDocument();
+    expect(unresolved).toBeChecked();
+
+    // Select "All Issues"
+    const all = screen.getByRole('radio', {name: 'All Issues'});
+    expect(all).toBeInTheDocument();
+    expect(all).not.toBeChecked();
+    userEvent.click(all);
+
+    expect(router.replace).toHaveBeenCalledWith(
+      expect.objectContaining({query: {status: ''}})
     );
   });
 
@@ -131,10 +155,5 @@ describe('UserFeedback', function () {
     render(<UserFeedback {...params} />, {context: routerContext});
 
     expect(screen.getByTestId('user-feedback-empty')).toBeInTheDocument();
-
-    expect(screen.getByRole('button', {name: 'All Issues'})).toHaveAttribute(
-      'href',
-      'sentry?project=112&project=113&status='
-    );
   });
 });

+ 16 - 10
static/app/views/userFeedback/index.tsx

@@ -3,8 +3,6 @@ import styled from '@emotion/styled';
 import {withProfiler} from '@sentry/react';
 import omit from 'lodash/omit';
 
-import {Button} from 'sentry/components/button';
-import ButtonBar from 'sentry/components/buttonBar';
 import DatePageFilter from 'sentry/components/datePageFilter';
 import EnvironmentPageFilter from 'sentry/components/environmentPageFilter';
 import {EventUserFeedback} from 'sentry/components/events/userFeedback';
@@ -18,6 +16,7 @@ import {PageHeadingQuestionTooltip} from 'sentry/components/pageHeadingQuestionT
 import Pagination from 'sentry/components/pagination';
 import {Panel} from 'sentry/components/panels';
 import ProjectPageFilter from 'sentry/components/projectPageFilter';
+import {SegmentedControl} from 'sentry/components/segmentedControl';
 import {t} from 'sentry/locale';
 import space from 'sentry/styles/space';
 import {Organization, UserReport} from 'sentry/types';
@@ -115,7 +114,7 @@ class OrganizationUserFeedback extends AsyncView<Props, State> {
   }
 
   renderBody() {
-    const {organization} = this.props;
+    const {organization, router} = this.props;
     const {location} = this.props;
     const {pathname, search, query} = location;
     const {status} = getQuery(search);
@@ -148,14 +147,21 @@ class OrganizationUserFeedback extends AsyncView<Props, State> {
                   <EnvironmentPageFilter />
                   <DatePageFilter alignDropdown="right" />
                 </PageFilterBar>
-                <ButtonBar active={!Array.isArray(status) ? status || '' : ''} merged>
-                  <Button barId="unresolved" to={{pathname, query: unresolvedQuery}}>
+                <SegmentedControl
+                  aria-label={t('Issue Status')}
+                  value={!Array.isArray(status) ? status || '' : ''}
+                  onChange={key =>
+                    router.replace({
+                      pathname,
+                      query: key === 'unresolved' ? unresolvedQuery : allIssuesQuery,
+                    })
+                  }
+                >
+                  <SegmentedControl.Item key="unresolved">
                     {t('Unresolved')}
-                  </Button>
-                  <Button barId="" to={{pathname, query: allIssuesQuery}}>
-                    {t('All Issues')}
-                  </Button>
-                </ButtonBar>
+                  </SegmentedControl.Item>
+                  <SegmentedControl.Item key="">{t('All Issues')}</SegmentedControl.Item>
+                </SegmentedControl>
               </Filters>
               {this.renderStreamBody()}
               <Pagination pageLinks={reportListPageLinks} />