Browse Source

feat(feedback): introduce banner with link to set up docs (#59155)

Until we have a better way to show set up docs when the feedback state
is empty because no feedback was received, show a setup banner to
everyone:

<img width="1220" alt="SCR-20231031-neda"
src="https://github.com/getsentry/sentry/assets/56095982/e8b43f15-15da-4c3e-bd17-6018643c6ce5">

---------

Co-authored-by: Ryan Albrecht <ryan.albrecht@sentry.io>
Michelle Zhang 1 year ago
parent
commit
059003586f

+ 50 - 0
static/app/components/feedback/feedbackSetupBanner.tsx

@@ -0,0 +1,50 @@
+import {CSSProperties} from 'react';
+import styled from '@emotion/styled';
+
+import replaysDeadRageBackground from 'sentry-images/spot/replay-dead-rage-changelog.svg';
+
+import {LinkButton} from 'sentry/components/button';
+import PageBanner from 'sentry/components/replays/pageBanner';
+import {IconBroadcast} from 'sentry/icons';
+import {t, tct} from 'sentry/locale';
+import useDismissAlert from 'sentry/utils/useDismissAlert';
+
+interface Props {
+  style?: CSSProperties;
+}
+
+const LOCAL_STORAGE_KEY = 'feedback-set-up-alert-dismissed';
+
+export default function FeedbackSetupBanner({style}: Props) {
+  const {dismiss, isDismissed} = useDismissAlert({key: LOCAL_STORAGE_KEY});
+
+  const docsButton = (
+    <LinkButton
+      external
+      href="https://github.com/getsentry/sentry-javascript/blob/develop/packages/feedback/README.md"
+      priority="primary"
+    >
+      {t('Set Up Now')}
+    </LinkButton>
+  );
+
+  return isDismissed ? null : (
+    <PageBanner
+      style={style}
+      button={docsButton}
+      description={t(
+        "Users can submit feedback anytime on issues they're experiencing on your app via our feedback widget."
+      )}
+      heading={t('Introducing the New User Feedback')}
+      icon={<IconBroadcast size="sm" />}
+      image={replaysDeadRageBackground}
+      title={tct("[blue:What's New]", {blue: <Blue />})}
+      onDismiss={dismiss}
+    />
+  );
+}
+
+const Blue = styled('span')`
+  color: ${p => p.theme.blue400};
+  font-weight: bold;
+`;

+ 5 - 2
static/app/views/feedback/feedbackListPage.tsx

@@ -4,6 +4,7 @@ import styled from '@emotion/styled';
 import ErrorBoundary from 'sentry/components/errorBoundary';
 import FeedbackFilters from 'sentry/components/feedback/feedbackFilters';
 import FeedbackItemLoader from 'sentry/components/feedback/feedbackItem/feedbackItemLoader';
+import FeedbackSetupBanner from 'sentry/components/feedback/feedbackSetupBanner';
 import FeedbackList from 'sentry/components/feedback/list/feedbackList';
 import {FeedbackQueryKeys} from 'sentry/components/feedback/useFeedbackQueryKeys';
 import FullViewport from 'sentry/components/layouts/fullViewport';
@@ -32,6 +33,7 @@ export default function FeedbackListPage({}: Props) {
           <PageFiltersContainer>
             <ErrorBoundary>
               <LayoutGrid>
+                <FeedbackSetupBanner style={{gridArea: 'banner', marginTop: '16px'}} />
                 <FeedbackFilters style={{gridArea: 'filters'}} />
                 <Container style={{gridArea: 'list'}}>
                   <FeedbackList />
@@ -53,13 +55,14 @@ const LayoutGrid = styled('div')`
 
   height: 100%;
   width: 100%;
-  padding: ${space(2)} ${space(4)};
+  padding: 0 ${space(4)} ${space(2)} ${space(4)};
   overflow: hidden;
 
   display: grid;
   grid-template-columns: minmax(390px, 1fr) 2fr;
-  grid-template-rows: max-content 1fr;
+  grid-template-rows: max-content max-content 1fr;
   grid-template-areas:
+    'banner banner'
     'filters details'
     'list details';
   gap: ${space(2)};