Browse Source

feat(settings): Remove DropdownLink from project debug (#80210)

Scott Cooper 4 months ago
parent
commit
f419dd465b

+ 48 - 144
static/app/views/settings/projectDebugFiles/sources/customRepositories/actions.tsx

@@ -1,15 +1,10 @@
 import {Fragment} from 'react';
-import styled from '@emotion/styled';
 
-import MenuItemActionLink from 'sentry/components/actions/menuItemActionLink';
 import {Button} from 'sentry/components/button';
-import ButtonBar from 'sentry/components/buttonBar';
-import ConfirmDelete from 'sentry/components/confirmDelete';
-import DropdownLink from 'sentry/components/dropdownLink';
-import {Tooltip} from 'sentry/components/tooltip';
+import {openConfirmModal} from 'sentry/components/confirm';
+import {DropdownMenu} from 'sentry/components/dropdownMenu';
 import {IconEllipsis} from 'sentry/icons/iconEllipsis';
 import {t} from 'sentry/locale';
-import {space} from 'sentry/styles/space';
 import TextBlock from 'sentry/views/settings/components/text/textBlock';
 
 type Props = {
@@ -18,157 +13,66 @@ type Props = {
   onDelete: () => void;
   onEdit: () => void;
   repositoryName: string;
-  disabled?: boolean;
-  syncNowButton?: React.ReactElement;
 };
 
-function Actions({
-  repositoryName,
-  disabled,
-  onEdit,
-  onDelete,
-  hasFeature,
-  hasAccess,
-  syncNowButton,
-}: Props) {
-  function renderConfirmDelete(element: React.ReactElement) {
-    return (
-      <ConfirmDelete
-        confirmText={t('Delete Repository')}
-        message={
-          <Fragment>
-            <TextBlock>
-              <strong>
-                {t('Removing this repository applies instantly to new events.')}
-              </strong>
-            </TextBlock>
-            <TextBlock>
-              {t(
-                'Debug files from this repository will not be used to symbolicate future events. This may create new issues and alert members in your organization.'
-              )}
-            </TextBlock>
-          </Fragment>
-        }
-        confirmInput={repositoryName}
-        priority="danger"
-        onConfirm={onDelete}
-      >
-        {element}
-      </ConfirmDelete>
-    );
-  }
-
-  const actionsDisabled = !hasAccess || !hasFeature || disabled;
+function Actions({repositoryName, onEdit, onDelete, hasFeature, hasAccess}: Props) {
+  const actionsDisabled = !hasAccess || !hasFeature;
 
   return (
-    <StyledButtonBar gap={1}>
-      {syncNowButton}
-      <ButtonTooltip
-        title={
-          !hasFeature
-            ? undefined
-            : !hasAccess
-              ? t(
-                  'You do not have permission to edit custom repositories configurations.'
-                )
-              : undefined
-        }
-        disabled={actionsDisabled}
-      >
-        <ActionBtn disabled={actionsDisabled} onClick={onEdit} size="sm">
-          {t('Configure')}
-        </ActionBtn>
-      </ButtonTooltip>
-
-      {actionsDisabled ? (
-        <ButtonTooltip
+    <DropdownMenu
+      isDisabled={actionsDisabled}
+      trigger={triggerProps => (
+        <Button
+          size="xs"
+          aria-label={t('Actions')}
+          disabled={actionsDisabled}
           title={
             !hasFeature
               ? undefined
               : !hasAccess
                 ? t(
-                    'You do not have permission to delete custom repositories configurations.'
+                    'You do not have permission to edit and delete custom repositories configurations.'
                   )
                 : undefined
           }
-          disabled={actionsDisabled}
-        >
-          <ActionBtn size="sm" disabled>
-            {t('Delete')}
-          </ActionBtn>
-        </ButtonTooltip>
-      ) : (
-        renderConfirmDelete(<ActionBtn size="sm">{t('Delete')}</ActionBtn>)
+          icon={<IconEllipsis />}
+          {...triggerProps}
+        />
       )}
-      <DropDownWrapper>
-        <DropdownLink
-          caret={false}
-          disabled={actionsDisabled}
-          customTitle={
-            <StyledButton
-              size="xs"
-              aria-label={t('Actions')}
-              disabled={actionsDisabled}
-              title={
-                !hasFeature
-                  ? undefined
-                  : !hasAccess
-                    ? t(
-                        'You do not have permission to edit and delete custom repositories configurations.'
-                      )
-                    : undefined
-              }
-              icon={<IconEllipsis />}
-            />
-          }
-          anchorRight
-        >
-          <MenuItemActionLink onClick={onEdit}>{t('Configure')}</MenuItemActionLink>
-          {renderConfirmDelete(<MenuItemActionLink>{t('Delete')}</MenuItemActionLink>)}
-        </DropdownLink>
-      </DropDownWrapper>
-    </StyledButtonBar>
+      position="bottom-end"
+      items={[
+        {
+          key: 'configure',
+          label: t('Configure'),
+          onAction: onEdit,
+        },
+        {
+          key: 'delete',
+          label: t('Delete'),
+          onAction: () => {
+            openConfirmModal({
+              header: <h6>{t('Delete %s?', repositoryName)}</h6>,
+              message: (
+                <Fragment>
+                  <TextBlock>
+                    <strong>
+                      {t('Removing this repository applies instantly to new events.')}
+                    </strong>
+                  </TextBlock>
+                  <TextBlock>
+                    {t(
+                      'Debug files from this repository will not be used to symbolicate future events. This may create new issues and alert members in your organization.'
+                    )}
+                  </TextBlock>
+                </Fragment>
+              ),
+              onConfirm: onDelete,
+            });
+          },
+        },
+      ]}
+    />
   );
 }
 
 export default Actions;
-
-const StyledButton = styled(Button)`
-  height: 32px;
-`;
-
-const StyledButtonBar = styled(ButtonBar)`
-  gap: ${space(1)};
-
-  grid-column: 2/2;
-  grid-row: 4/4;
-  grid-auto-flow: row;
-  margin-top: ${space(0.5)};
-
-  @media (min-width: ${p => p.theme.breakpoints.small}) {
-    grid-column: 3/3;
-    grid-row: 1/3;
-    grid-auto-flow: column;
-    margin-top: 0;
-  }
-`;
-
-const ButtonTooltip = styled(Tooltip)`
-  @media (min-width: ${p => p.theme.breakpoints.small}) {
-    display: none;
-  }
-`;
-
-const ActionBtn = styled(Button)`
-  width: 100%;
-  @media (min-width: ${p => p.theme.breakpoints.small}) {
-    display: none;
-  }
-`;
-
-const DropDownWrapper = styled('div')`
-  display: none;
-  @media (min-width: ${p => p.theme.breakpoints.small}) {
-    display: block;
-  }
-`;

+ 3 - 5
static/app/views/settings/projectDebugFiles/sources/customRepositories/index.tsx

@@ -26,8 +26,6 @@ import {defined} from 'sentry/utils';
 import Repository from './repository';
 import {dropDownItems, expandKeys, getRequestMessages} from './utils';
 
-const SECTION_TITLE = t('Custom Repositories');
-
 type Props = {
   api: Client;
   customRepositories: CustomRepo[];
@@ -178,7 +176,7 @@ function CustomRepositories({
             return (
               <Panel>
                 <PanelHeader hasButtons>
-                  {SECTION_TITLE}
+                  {t('Custom Repositories')}
                   <Tooltip
                     title={
                       !hasAccess
@@ -223,9 +221,9 @@ function CustomRepositories({
                       <p>{t('No custom repositories configured')}</p>
                     </EmptyStateWarning>
                   ) : (
-                    repositories.map((repository, index) => (
+                    repositories.map(repository => (
                       <Repository
-                        key={index}
+                        key={repository.id}
                         repository={repository}
                         hasFeature={hasFeature}
                         hasAccess={hasAccess}

+ 16 - 37
static/app/views/settings/projectDebugFiles/sources/customRepositories/repository.tsx

@@ -16,19 +16,21 @@ type Props = {
 };
 
 function Repository({repository, onDelete, onEdit, hasFeature, hasAccess}: Props) {
-  const {id, name, type} = repository;
-
   return (
     <StyledPanelItem>
-      <Name>{name}</Name>
-      <TypeAndStatus>{customRepoTypeLabel[type]}</TypeAndStatus>
-      <CustomRepositoryActions
-        repositoryName={name}
-        hasFeature={hasFeature}
-        hasAccess={hasAccess}
-        onDelete={() => onDelete(id)}
-        onEdit={() => onEdit(id)}
-      />
+      <div>
+        <div>{repository.name}</div>
+        <TypeAndStatus>{customRepoTypeLabel[repository.type]}</TypeAndStatus>
+      </div>
+      <div>
+        <CustomRepositoryActions
+          repositoryName={repository.name}
+          hasFeature={hasFeature}
+          hasAccess={hasAccess}
+          onDelete={() => onDelete(repository.id)}
+          onEdit={() => onEdit(repository.id)}
+        />
+      </div>
     </StyledPanelItem>
   );
 }
@@ -36,24 +38,10 @@ function Repository({repository, onDelete, onEdit, hasFeature, hasAccess}: Props
 export default Repository;
 
 const StyledPanelItem = styled(PanelItem)`
-  display: grid;
-  align-items: flex-start;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
   gap: ${space(1)};
-
-  grid-template-columns: max-content 1fr;
-
-  @media (min-width: ${p => p.theme.breakpoints.small}) {
-    grid-template-columns: max-content 1fr max-content;
-  }
-`;
-
-const Name = styled('div')`
-  grid-column: 2/2;
-
-  @media (min-width: ${p => p.theme.breakpoints.small}) {
-    grid-column: 2/3;
-    grid-row: 1/2;
-  }
 `;
 
 const TypeAndStatus = styled('div')`
@@ -62,13 +50,4 @@ const TypeAndStatus = styled('div')`
   display: flex;
   flex-wrap: wrap;
   align-items: center;
-
-  grid-column: 2/2;
-  gap: ${space(1.5)};
-
-  @media (min-width: ${p => p.theme.breakpoints.small}) {
-    grid-column: 2/3;
-    grid-row: 2/2;
-    gap: ${space(1)};
-  }
 `;