Browse Source

feat(replays): Delete replay button (#39600)

Adds a button that calls the replay api to delete a replay

Redirects back to replay list page on successful delete or will show on a toast message on delete failure

![Screen Shot 2022-10-04 at 9 06 37
AM](https://user-images.githubusercontent.com/3721977/193827755-09cb797f-9cf6-4683-abc4-0bbdfbdc3acc.png)

Closes #39554
Dane Grant 2 years ago
parent
commit
9c161d56ef

+ 39 - 0
static/app/components/replays/deleteButton.tsx

@@ -0,0 +1,39 @@
+import * as Sentry from '@sentry/react';
+
+import {addErrorMessage} from 'sentry/actionCreators/indicator';
+import Button from 'sentry/components/button';
+import {IconDelete} from 'sentry/icons';
+import {t} from 'sentry/locale';
+import useApi from 'sentry/utils/useApi';
+import {useRouteContext} from 'sentry/utils/useRouteContext';
+
+function DeleteButton() {
+  const api = useApi();
+  const {params, router} = useRouteContext();
+
+  const orgSlug = params.orgId;
+  const [projectSlug, replayId] = params.replaySlug.split(':');
+
+  const handleDelete = async () => {
+    try {
+      await api.requestPromise(
+        `/projects/${orgSlug}/${projectSlug}/replays/${replayId}/`,
+        {
+          method: 'DELETE',
+        }
+      );
+      router.replace(`/organizations/${orgSlug}/replays/`);
+    } catch (err) {
+      addErrorMessage(t('Failed to delete replay'));
+      Sentry.captureException(err);
+    }
+  };
+
+  return (
+    <Button size="xs" icon={<IconDelete size="xs" />} onClick={handleDelete}>
+      {t('Delete')}
+    </Button>
+  );
+}
+
+export default DeleteButton;

+ 3 - 1
static/app/views/replays/detail/page.tsx

@@ -3,6 +3,7 @@ import styled from '@emotion/styled';
 
 import {FeatureFeedback} from 'sentry/components/featureFeedback';
 import * as Layout from 'sentry/components/layouts/thirds';
+import DeleteButton from 'sentry/components/replays/deleteButton';
 import DetailsPageBreadcrumbs from 'sentry/components/replays/header/detailsPageBreadcrumbs';
 import {CrumbWalker} from 'sentry/components/replays/walker/urlWalker';
 import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle';
@@ -32,6 +33,7 @@ function Page({children, crumbs, orgSlug, replayRecord}: Props) {
         <DetailsPageBreadcrumbs orgSlug={orgSlug} replayRecord={replayRecord} />
       </HeaderContent>
       <ButtonActionsWrapper>
+        <DeleteButton />
         <ChooseLayout />
         <FeatureFeedback featureName="replay" buttonProps={{size: 'xs'}} />
       </ButtonActionsWrapper>
@@ -71,7 +73,7 @@ const HeaderContent = styled(Layout.HeaderContent)`
 // TODO(replay); This could make a lot of sense to put inside HeaderActions by default
 const ButtonActionsWrapper = styled(Layout.HeaderActions)`
   display: grid;
-  grid-template-columns: repeat(2, max-content);
+  grid-template-columns: repeat(3, max-content);
   justify-content: flex-end;
   gap: ${space(1)};
 `;