From 316bf24f4a9da7259c1aebf0bb6ee792555ea90e Mon Sep 17 00:00:00 2001 From: Andrew Liu <159852527+aliu39@users.noreply.github.com> Date: Mon, 22 Jul 2024 14:28:44 -0700 Subject: [PATCH 1/4] fix(toolbar): hide feedback panel when submit feedback form opens --- .../components/feedback/feedbackPanel.tsx | 9 ++++++-- .../devtoolbar/components/panelLayout.tsx | 23 +++++++++++++++++-- .../devtoolbar/hooks/useSDKFeedbackButton.tsx | 12 +++++++--- 3 files changed, 37 insertions(+), 7 deletions(-) diff --git a/static/app/components/devtoolbar/components/feedback/feedbackPanel.tsx b/static/app/components/devtoolbar/components/feedback/feedbackPanel.tsx index 08aa45f01383a3..d9eb1bf9e85bdd 100644 --- a/static/app/components/devtoolbar/components/feedback/feedbackPanel.tsx +++ b/static/app/components/devtoolbar/components/feedback/feedbackPanel.tsx @@ -1,4 +1,4 @@ -import {useMemo} from 'react'; +import {useMemo, useState} from 'react'; import {css} from '@emotion/react'; import ActorAvatar from 'sentry/components/avatar/actorAvatar'; @@ -34,7 +34,11 @@ import SentryAppLink from '../sentryAppLink'; import useInfiniteFeedbackList from './useInfiniteFeedbackList'; export default function FeedbackPanel() { - const buttonRef = useSDKFeedbackButton(); + const [visible, setVisible] = useState(true); + const buttonRef = useSDKFeedbackButton({ + onFormOpen: () => setVisible(false), + onFormClose: () => setVisible(true), + }); const transactionName = useCurrentTransactionName(); const queryResult = useInfiniteFeedbackList({ query: `url:*${transactionName}`, @@ -58,6 +62,7 @@ export default function FeedbackPanel() { ) : null } + visible={visible} >
diff --git a/static/app/components/devtoolbar/components/panelLayout.tsx b/static/app/components/devtoolbar/components/panelLayout.tsx index 34df3ce5131b16..ba04358b270cdc 100644 --- a/static/app/components/devtoolbar/components/panelLayout.tsx +++ b/static/app/components/devtoolbar/components/panelLayout.tsx @@ -1,3 +1,5 @@ +import {css} from '@emotion/react'; + import {buttonCss} from 'sentry/components/devtoolbar/styles/typography'; import {panelCss, panelHeadingCss, panelSectionCss} from '../styles/panel'; @@ -8,11 +10,28 @@ interface Props { children?: React.ReactNode; titleLeft?: React.ReactNode; titleRight?: React.ReactNode; + visible?: boolean; } -export default function PanelLayout({children, title, titleLeft, titleRight}: Props) { +export default function PanelLayout({ + children, + title, + titleLeft, + titleRight, + visible = true, +}: Props) { return ( - + {title ? (
{titleLeft} diff --git a/static/app/components/devtoolbar/hooks/useSDKFeedbackButton.tsx b/static/app/components/devtoolbar/hooks/useSDKFeedbackButton.tsx index 1024f5826be957..314e840e9cc724 100644 --- a/static/app/components/devtoolbar/hooks/useSDKFeedbackButton.tsx +++ b/static/app/components/devtoolbar/hooks/useSDKFeedbackButton.tsx @@ -2,17 +2,23 @@ import {useEffect, useRef} from 'react'; import useConfiguration from './useConfiguration'; -export function useSDKFeedbackButton() { +export function useSDKFeedbackButton({ + onFormClose, + onFormOpen, +}: { + onFormClose?: () => void; + onFormOpen?: () => void; +}) { const buttonRef = useRef(null); const {SentrySDK} = useConfiguration(); const feedback = SentrySDK && 'getFeedback' in SentrySDK && SentrySDK.getFeedback(); useEffect(() => { if (feedback && buttonRef.current) { - return feedback.attachTo(buttonRef.current, {}); + return feedback.attachTo(buttonRef.current, {onFormOpen, onFormClose}); } return () => {}; - }, [feedback]); + }, [feedback, onFormOpen, onFormClose]); return feedback ? buttonRef : undefined; } From 0527baf279765fbb9fdb3fcd2f47e075b5b0fe82 Mon Sep 17 00:00:00 2001 From: Ryan Albrecht Date: Tue, 23 Jul 2024 11:30:03 -0700 Subject: [PATCH 2/4] nmove state into a provider so the css change can cover as well as the panel(s) --- .../components/devtoolbar/components/app.tsx | 4 +++- .../components/feedback/feedbackPanel.tsx | 20 ++++++++++------ .../devtoolbar/components/panelLayout.tsx | 23 ++----------------- .../devtoolbar/components/providers.tsx | 5 +++- .../devtoolbar/hooks/useVisibility.tsx | 20 ++++++++++++++++ 5 files changed, 42 insertions(+), 30 deletions(-) create mode 100644 static/app/components/devtoolbar/hooks/useVisibility.tsx diff --git a/static/app/components/devtoolbar/components/app.tsx b/static/app/components/devtoolbar/components/app.tsx index 47c8bb7ad8d86e..11e1a296e2d520 100644 --- a/static/app/components/devtoolbar/components/app.tsx +++ b/static/app/components/devtoolbar/components/app.tsx @@ -5,6 +5,7 @@ import LoadingTriangle from 'sentry/components/loadingTriangle'; import {useSessionStorage} from 'sentry/utils/useSessionStorage'; import usePlacementCss from '../hooks/usePlacementCss'; +import useVisibility from '../hooks/useVisibility'; import {fixedContainerBaseCss} from '../styles/fixedContainer'; import {avatarCss, globalCss, loadingIndicatorCss} from '../styles/global'; import {resetFlexColumnCss} from '../styles/reset'; @@ -15,6 +16,7 @@ import PanelRouter from './panelRouter'; export default function App() { const placement = usePlacementCss(); + const [visibility] = useVisibility(); const [isHidden, setIsHidden] = useSessionStorage('hide_employee_devtoolbar', false); if (isHidden) { return null; @@ -25,7 +27,7 @@ export default function App() { -
+
{isHidden ? null : ( diff --git a/static/app/components/devtoolbar/components/feedback/feedbackPanel.tsx b/static/app/components/devtoolbar/components/feedback/feedbackPanel.tsx index d9eb1bf9e85bdd..ba33b85d0b6ca9 100644 --- a/static/app/components/devtoolbar/components/feedback/feedbackPanel.tsx +++ b/static/app/components/devtoolbar/components/feedback/feedbackPanel.tsx @@ -1,4 +1,4 @@ -import {useMemo, useState} from 'react'; +import {useMemo} from 'react'; import {css} from '@emotion/react'; import ActorAvatar from 'sentry/components/avatar/actorAvatar'; @@ -12,6 +12,7 @@ import useReplayCount from 'sentry/utils/replayCount/useReplayCount'; import useConfiguration from '../../hooks/useConfiguration'; import useCurrentTransactionName from '../../hooks/useCurrentTransactionName'; import {useSDKFeedbackButton} from '../../hooks/useSDKFeedbackButton'; +import useVisibility from '../../hooks/useVisibility'; import { badgeWithLabelCss, gridFlexEndCss, @@ -34,11 +35,17 @@ import SentryAppLink from '../sentryAppLink'; import useInfiniteFeedbackList from './useInfiniteFeedbackList'; export default function FeedbackPanel() { - const [visible, setVisible] = useState(true); - const buttonRef = useSDKFeedbackButton({ - onFormOpen: () => setVisible(false), - onFormClose: () => setVisible(true), - }); + const [, setVisible] = useVisibility(); + + const buttonRef = useSDKFeedbackButton( + useMemo( + () => ({ + onFormOpen: () => setVisible('hidden'), + onFormClose: () => setVisible('visible'), + }), + [setVisible] + ) + ); const transactionName = useCurrentTransactionName(); const queryResult = useInfiniteFeedbackList({ query: `url:*${transactionName}`, @@ -62,7 +69,6 @@ export default function FeedbackPanel() { ) : null } - visible={visible} >
diff --git a/static/app/components/devtoolbar/components/panelLayout.tsx b/static/app/components/devtoolbar/components/panelLayout.tsx index ba04358b270cdc..34df3ce5131b16 100644 --- a/static/app/components/devtoolbar/components/panelLayout.tsx +++ b/static/app/components/devtoolbar/components/panelLayout.tsx @@ -1,5 +1,3 @@ -import {css} from '@emotion/react'; - import {buttonCss} from 'sentry/components/devtoolbar/styles/typography'; import {panelCss, panelHeadingCss, panelSectionCss} from '../styles/panel'; @@ -10,28 +8,11 @@ interface Props { children?: React.ReactNode; titleLeft?: React.ReactNode; titleRight?: React.ReactNode; - visible?: boolean; } -export default function PanelLayout({ - children, - title, - titleLeft, - titleRight, - visible = true, -}: Props) { +export default function PanelLayout({children, title, titleLeft, titleRight}: Props) { return ( - + {title ? (
{titleLeft} diff --git a/static/app/components/devtoolbar/components/providers.tsx b/static/app/components/devtoolbar/components/providers.tsx index 74556468e9cd42..9b24802bd55bc0 100644 --- a/static/app/components/devtoolbar/components/providers.tsx +++ b/static/app/components/devtoolbar/components/providers.tsx @@ -7,6 +7,7 @@ import {lightTheme} from 'sentry/utils/theme'; import {ConfigurationContextProvider} from '../hooks/useConfiguration'; import {ToolbarRouterContextProvider} from '../hooks/useToolbarRoute'; +import {VisibilityContextProvider} from '../hooks/useVisibility'; import type {Configuration} from '../types'; interface Props { @@ -35,7 +36,9 @@ export default function Providers({children, config, container}: Props) { - {children} + + {children} + diff --git a/static/app/components/devtoolbar/hooks/useVisibility.tsx b/static/app/components/devtoolbar/hooks/useVisibility.tsx new file mode 100644 index 00000000000000..59c7cfb320eb9b --- /dev/null +++ b/static/app/components/devtoolbar/hooks/useVisibility.tsx @@ -0,0 +1,20 @@ +import type {Dispatch, ReactNode, SetStateAction} from 'react'; +import {createContext, useContext, useState} from 'react'; + +type State = 'visible' | 'hidden'; + +const VisibilityContext = createContext<[State, Dispatch>]>([ + 'visible', + () => {}, +]); + +export function VisibilityContextProvider({children}: {children: ReactNode}) { + const state = useState('visible'); + return ( + {children} + ); +} + +export default function useVisibility() { + return useContext(VisibilityContext); +} From 7569192fc31265ac8f1c3d8793ed8cca07bebea6 Mon Sep 17 00:00:00 2001 From: Andrew Liu <159852527+aliu39@users.noreply.github.com> Date: Tue, 23 Jul 2024 12:06:23 -0700 Subject: [PATCH 3/4] Use CSSProperties type --- static/app/components/devtoolbar/hooks/useVisibility.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/static/app/components/devtoolbar/hooks/useVisibility.tsx b/static/app/components/devtoolbar/hooks/useVisibility.tsx index 59c7cfb320eb9b..5f9a31f809beff 100644 --- a/static/app/components/devtoolbar/hooks/useVisibility.tsx +++ b/static/app/components/devtoolbar/hooks/useVisibility.tsx @@ -1,7 +1,7 @@ -import type {Dispatch, ReactNode, SetStateAction} from 'react'; +import type {CSSProperties, Dispatch, ReactNode, SetStateAction} from 'react'; import {createContext, useContext, useState} from 'react'; -type State = 'visible' | 'hidden'; +type State = CSSProperties['visibility']; const VisibilityContext = createContext<[State, Dispatch>]>([ 'visible', From 7822bf748a439c065f4897bef61f518bbabd9240 Mon Sep 17 00:00:00 2001 From: Andrew Liu <159852527+aliu39@users.noreply.github.com> Date: Tue, 23 Jul 2024 12:08:05 -0700 Subject: [PATCH 4/4] Rename isHidden to isDisabled to avoid confusion with visible --- static/app/components/devtoolbar/components/app.tsx | 11 +++++++---- .../components/devtoolbar/components/navigation.tsx | 8 ++++++-- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/static/app/components/devtoolbar/components/app.tsx b/static/app/components/devtoolbar/components/app.tsx index 11e1a296e2d520..2696a86a23a0b4 100644 --- a/static/app/components/devtoolbar/components/app.tsx +++ b/static/app/components/devtoolbar/components/app.tsx @@ -17,8 +17,11 @@ import PanelRouter from './panelRouter'; export default function App() { const placement = usePlacementCss(); const [visibility] = useVisibility(); - const [isHidden, setIsHidden] = useSessionStorage('hide_employee_devtoolbar', false); - if (isHidden) { + const [isDisabled, setIsDisabled] = useSessionStorage( + 'hide_employee_devtoolbar', + false + ); + if (isDisabled) { return null; } @@ -28,9 +31,9 @@ export default function App() {
- {isHidden ? null : ( + {isDisabled ? null : ( - + }> diff --git a/static/app/components/devtoolbar/components/navigation.tsx b/static/app/components/devtoolbar/components/navigation.tsx index e05c418e745894..5fd892e86238a7 100644 --- a/static/app/components/devtoolbar/components/navigation.tsx +++ b/static/app/components/devtoolbar/components/navigation.tsx @@ -9,7 +9,11 @@ import useToolbarRoute from '../hooks/useToolbarRoute'; import {navigationButtonCss, navigationCss} from '../styles/navigation'; import {resetButtonCss, resetDialogCss} from '../styles/reset'; -export default function Navigation({setIsHidden}: {setIsHidden: (val: boolean) => void}) { +export default function Navigation({ + setIsDisabled, +}: { + setIsDisabled: (val: boolean) => void; +}) { const {trackAnalytics} = useConfiguration(); const placement = usePlacementCss(); @@ -26,7 +30,7 @@ export default function Navigation({setIsHidden}: {setIsHidden: (val: boolean) = } /> { - setIsHidden(true); + setIsDisabled(true); trackAnalytics?.({ eventKey: `devtoolbar.nav.hide.click`, eventName: `devtoolbar: Hide devtoolbar`,