Browse Source

feat(issue-stream): Hide checkboxes and actions on small screen sizes [UP-155] (#38982)

Malachi Willey 2 years ago
parent
commit
8b78d3e287

+ 1 - 1
static/app/components/stream/group.tsx

@@ -412,7 +412,7 @@ function BaseGroupRow({
     <Wrapper
       data-test-id="group"
       data-test-reviewed={reviewed}
-      onClick={displayReprocessingLayout ? undefined : wrapperToggle}
+      onClick={displayReprocessingLayout || !canSelect ? undefined : wrapperToggle}
       reviewed={reviewed}
       useTintRow={useTintRow ?? true}
     >

+ 3 - 26
static/app/views/issueList/actions/actionSet.tsx

@@ -1,5 +1,5 @@
+import {Fragment} from 'react';
 import {useTheme} from '@emotion/react';
-import styled from '@emotion/styled';
 
 import ActionLink from 'sentry/components/actions/actionLink';
 import IgnoreActions from 'sentry/components/actions/ignore';
@@ -9,7 +9,6 @@ import {MenuItemProps} from 'sentry/components/dropdownMenuItem';
 import {IconEllipsis} from 'sentry/icons';
 import {t} from 'sentry/locale';
 import GroupStore from 'sentry/stores/groupStore';
-import space from 'sentry/styles/space';
 import {
   BaseGroup,
   IssueCategory,
@@ -24,7 +23,6 @@ import useOrganization from 'sentry/utils/useOrganization';
 
 import ResolveActions from './resolveActions';
 import ReviewAction from './reviewAction';
-import IssueListSortOptions from './sortOptions';
 import {ConfirmAction, getConfirm, getLabel} from './utils';
 
 type Props = {
@@ -35,11 +33,9 @@ type Props = {
   onDelete: () => void;
   onMerge: () => void;
   onShouldConfirm: (action: ConfirmAction) => boolean;
-  onSortChange: (sort: string) => void;
   onUpdate: (data?: any) => void;
   query: string;
   queryCount: number;
-  sort: string;
   selectedProjectSlug?: string;
 };
 
@@ -55,8 +51,6 @@ function ActionSet({
   onDelete,
   onMerge,
   selectedProjectSlug,
-  sort,
-  onSortChange,
 }: Props) {
   const organization = useOrganization();
   const numIssues = issues.size;
@@ -204,7 +198,7 @@ function ActionSet({
   ];
 
   return (
-    <Wrapper>
+    <Fragment>
       {selectedProjectSlug ? (
         <Projects orgId={organization.slug} slugs={[selectedProjectSlug]}>
           {({projects, initiallyLoaded, fetchError}) => {
@@ -284,8 +278,7 @@ function ActionSet({
         }}
         isDisabled={!anySelected}
       />
-      <IssueListSortOptions sort={sort} query={query} onSelect={onSortChange} />
-    </Wrapper>
+    </Fragment>
   );
 }
 
@@ -305,19 +298,3 @@ function isActionSupported(
 }
 
 export default ActionSet;
-
-const Wrapper = styled('div')`
-  @media (min-width: ${p => p.theme.breakpoints.small}) {
-    width: 66.66%;
-  }
-  @media (min-width: ${p => p.theme.breakpoints.large}) {
-    width: 50%;
-  }
-  flex: 1;
-  margin: 0 ${space(1)};
-  display: grid;
-  gap: ${space(0.5)};
-  grid-auto-flow: column;
-  justify-content: flex-start;
-  white-space: nowrap;
-`;

+ 47 - 24
static/app/views/issueList/actions/index.tsx

@@ -12,11 +12,14 @@ import SelectedGroupStore from 'sentry/stores/selectedGroupStore';
 import {useLegacyStore} from 'sentry/stores/useLegacyStore';
 import space from 'sentry/styles/space';
 import {Group, PageFilters, ResolutionStatusDetails} from 'sentry/types';
+import theme from 'sentry/utils/theme';
 import useApi from 'sentry/utils/useApi';
+import useMedia from 'sentry/utils/useMedia';
 import useOrganization from 'sentry/utils/useOrganization';
 
 import ActionSet from './actionSet';
 import Headers from './headers';
+import IssueListSortOptions from './sortOptions';
 import {
   BULK_LIMIT,
   BULK_LIMIT_STR,
@@ -68,6 +71,8 @@ function IssueListActions({
     setAllInQuerySelected,
   } = useSelectedGroupsState();
 
+  const disableActions = useMedia(`(max-width: ${theme.breakpoints.small})`);
+
   const numIssues = selectedIdsSet.size;
 
   function actionSelectedGroups(callback: (itemIds: string[] | undefined) => void) {
@@ -186,31 +191,36 @@ function IssueListActions({
   return (
     <Sticky>
       <StyledFlex>
-        <ActionsCheckbox isReprocessingQuery={displayReprocessingActions}>
-          <Checkbox
-            onChange={() => SelectedGroupStore.toggleSelectAll()}
-            checked={pageSelected || (anySelected ? 'indeterminate' : false)}
-            disabled={displayReprocessingActions}
-          />
-        </ActionsCheckbox>
+        {!disableActions && (
+          <ActionsCheckbox isReprocessingQuery={displayReprocessingActions}>
+            <Checkbox
+              onChange={() => SelectedGroupStore.toggleSelectAll()}
+              checked={pageSelected || (anySelected ? 'indeterminate' : false)}
+              disabled={displayReprocessingActions}
+            />
+          </ActionsCheckbox>
+        )}
         {!displayReprocessingActions && (
-          <ActionSet
-            sort={sort}
-            onSortChange={onSortChange}
-            queryCount={queryCount}
-            query={query}
-            issues={selectedIdsSet}
-            allInQuerySelected={allInQuerySelected}
-            anySelected={anySelected}
-            multiSelected={multiSelected}
-            selectedProjectSlug={selectedProjectSlug}
-            onShouldConfirm={action =>
-              shouldConfirm(action, {pageSelected, selectedIdsSet})
-            }
-            onDelete={handleDelete}
-            onMerge={handleMerge}
-            onUpdate={handleUpdate}
-          />
+          <HeaderButtonsWrapper>
+            {!disableActions && (
+              <ActionSet
+                queryCount={queryCount}
+                query={query}
+                issues={selectedIdsSet}
+                allInQuerySelected={allInQuerySelected}
+                anySelected={anySelected}
+                multiSelected={multiSelected}
+                selectedProjectSlug={selectedProjectSlug}
+                onShouldConfirm={action =>
+                  shouldConfirm(action, {pageSelected, selectedIdsSet})
+                }
+                onDelete={handleDelete}
+                onMerge={handleMerge}
+                onUpdate={handleUpdate}
+              />
+            )}
+            <IssueListSortOptions sort={sort} query={query} onSelect={onSortChange} />
+          </HeaderButtonsWrapper>
         )}
         <Headers
           onSelectStatsPeriod={onSelectStatsPeriod}
@@ -352,6 +362,19 @@ const ActionsCheckbox = styled('div')<{isReprocessingQuery: boolean}>`
   ${p => p.isReprocessingQuery && 'flex: 1'};
 `;
 
+const HeaderButtonsWrapper = styled('div')`
+  @media (min-width: ${p => p.theme.breakpoints.large}) {
+    width: 50%;
+  }
+  flex: 1;
+  margin: 0 ${space(1)};
+  display: grid;
+  gap: ${space(0.5)};
+  grid-auto-flow: column;
+  justify-content: flex-start;
+  white-space: nowrap;
+`;
+
 const SelectAllNotice = styled('div')`
   display: flex;
   flex-wrap: wrap;

+ 4 - 0
static/app/views/issueList/groupListBody.tsx

@@ -5,7 +5,9 @@ import {PanelBody} from 'sentry/components/panels';
 import StreamGroup from 'sentry/components/stream/group';
 import GroupStore from 'sentry/stores/groupStore';
 import {Group} from 'sentry/types';
+import theme from 'sentry/utils/theme';
 import useApi from 'sentry/utils/useApi';
+import useMedia from 'sentry/utils/useMedia';
 import useOrganization from 'sentry/utils/useOrganization';
 
 import NoGroupsHandler from './noGroupsHandler';
@@ -92,6 +94,7 @@ function GroupList({
 }: GroupListProps) {
   const topIssue = groupIds[0];
   const showInboxTime = sort === IssueSortOptions.INBOX;
+  const canSelect = !useMedia(`(max-width: ${theme.breakpoints.small})`);
 
   return (
     <PanelBody>
@@ -111,6 +114,7 @@ function GroupList({
             displayReprocessingLayout={displayReprocessingLayout}
             useFilteredStats
             showInboxTime={showInboxTime}
+            canSelect={canSelect}
           />
         );
       })}

+ 2 - 5
static/app/views/issueList/overview.tsx

@@ -1237,11 +1237,8 @@ class IssueListOverview extends Component<Props, State> {
                     memberList={this.state.memberList}
                     groupStatsPeriod={this.getGroupStatsPeriod()}
                     groupIds={groupIds}
-                    displayReprocessingLayout={this.displayReprocessingLayout(
-                      this.displayReprocessingTab(),
-                      this.getQuery()
-                    )}
-                    query={this.getQuery()}
+                    displayReprocessingLayout={displayReprocessingActions}
+                    query={query}
                     sort={this.getSort()}
                     selectedProjectIds={selection.projects}
                     loading={issuesLoading}