Skip to content

Commit

Permalink
ref(replays): tags is default tab for mobile replays (#67802)
Browse files Browse the repository at this point in the history
For mobile replays, all tabs except Tags are disabled, with a tooltip
saying coming soon:
<img width="709" alt="SCR-20240327-jyko-2"
src="https://github.com/getsentry/sentry/assets/56095982/711797bf-59a9-4010-9602-f87ca58105c6">


Attempting to route to some other `t_main` will result in the tags tab
being shown by default:
<img width="1264" alt="SCR-20240327-jyha"
src="https://github.com/getsentry/sentry/assets/56095982/59b61b1c-aae3-46ce-948d-95f526283dfc">

Closes #67692
  • Loading branch information
michellewzhang authored Mar 27, 2024
1 parent 095e301 commit a80842e
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 21 deletions.
16 changes: 10 additions & 6 deletions static/app/components/links/listLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,16 @@ const StyledLi = styled('li', {
${p =>
p.disabled &&
`
a {
color:${p.theme.disabled} !important;
pointer-events: none;
:hover {
color: ${p.theme.disabled} !important;
a {
color:${p.theme.disabled} !important;
:hover {
color: ${p.theme.disabled} !important;
}
cursor: default !important;
}
}
a:active {
pointer-events: none;
}
`}
`;
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ function Event({
}) {
const theme = useTheme();
const {onMouseEnter, onMouseLeave, onClickTimestamp} = useCrumbHandlers();
const {setActiveTab} = useActiveReplayTab();
const {setActiveTab} = useActiveReplayTab({});

const buttons = frames.map((frame, i) => (
<BreadcrumbItem
Expand Down
45 changes: 39 additions & 6 deletions static/app/utils/replays/hooks/useActiveReplayTab.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,21 +39,35 @@ describe('useActiveReplayTab', () => {
});

it('should use Breadcrumbs as a default', () => {
const {result} = reactHooks.renderHook(useActiveReplayTab);
const {result} = reactHooks.renderHook(useActiveReplayTab, {
initialProps: {},
});

expect(result.current.getActiveTab()).toBe(TabKey.BREADCRUMBS);
});

it('should use Tags as a default for video replays', () => {
const {result} = reactHooks.renderHook(useActiveReplayTab, {
initialProps: {isVideoReplay: true},
});

expect(result.current.getActiveTab()).toBe(TabKey.TAGS);
});

it('should use Breadcrumbs as a default, when there is a click search in the url', () => {
mockLocation('click.tag:button');

const {result} = reactHooks.renderHook(useActiveReplayTab);
const {result} = reactHooks.renderHook(useActiveReplayTab, {
initialProps: {},
});

expect(result.current.getActiveTab()).toBe(TabKey.BREADCRUMBS);
});

it('should allow case-insensitive tab names', () => {
const {result} = reactHooks.renderHook(useActiveReplayTab);
const {result} = reactHooks.renderHook(useActiveReplayTab, {
initialProps: {},
});
expect(result.current.getActiveTab()).toBe(TabKey.BREADCRUMBS);

result.current.setActiveTab('nEtWoRk');
Expand All @@ -64,7 +78,9 @@ describe('useActiveReplayTab', () => {
});

it('should set the default tab if the name is invalid', () => {
const {result} = reactHooks.renderHook(useActiveReplayTab);
const {result} = reactHooks.renderHook(useActiveReplayTab, {
initialProps: {},
});
expect(result.current.getActiveTab()).toBe(TabKey.BREADCRUMBS);

result.current.setActiveTab('foo bar');
Expand All @@ -74,12 +90,27 @@ describe('useActiveReplayTab', () => {
});
});

it('should set the default tab if the name is invalid for video replays', () => {
const {result} = reactHooks.renderHook(useActiveReplayTab, {
initialProps: {isVideoReplay: true},
});
expect(result.current.getActiveTab()).toBe(TabKey.TAGS);

result.current.setActiveTab('foo bar');
expect(mockPush).toHaveBeenLastCalledWith({
pathname: '',
query: {t_main: TabKey.TAGS},
});
});

it('should disallow PERF by default', () => {
mockOrganizationFixture({
features: [],
});

const {result} = reactHooks.renderHook(useActiveReplayTab);
const {result} = reactHooks.renderHook(useActiveReplayTab, {
initialProps: {},
});
expect(result.current.getActiveTab()).toBe(TabKey.BREADCRUMBS);

result.current.setActiveTab(TabKey.PERF);
Expand All @@ -93,7 +124,9 @@ describe('useActiveReplayTab', () => {
mockOrganizationFixture({
features: ['session-replay-trace-table'],
});
const {result} = reactHooks.renderHook(useActiveReplayTab);
const {result} = reactHooks.renderHook(useActiveReplayTab, {
initialProps: {},
});
expect(result.current.getActiveTab()).toBe(TabKey.BREADCRUMBS);

result.current.setActiveTab(TabKey.PERF);
Expand Down
4 changes: 2 additions & 2 deletions static/app/utils/replays/hooks/useActiveReplayTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ function isReplayTab(tab: string, organization: Organization): tab is TabKey {
return Object.values<string>(TabKey).includes(tab);
}

function useActiveReplayTab() {
const defaultTab = TabKey.BREADCRUMBS;
function useActiveReplayTab({isVideoReplay}: {isVideoReplay?: boolean}) {
const defaultTab = isVideoReplay ? TabKey.TAGS : TabKey.BREADCRUMBS;
const organization = useOrganization();
const {getParamValue, setParamValue} = useUrlParams('t_main', defaultTab);

Expand Down
8 changes: 6 additions & 2 deletions static/app/views/replays/detail/layout/focusArea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,12 @@ import PerfTable from 'sentry/views/replays/detail/perfTable/index';
import TagPanel from 'sentry/views/replays/detail/tagPanel';
import Trace from 'sentry/views/replays/detail/trace/index';

export default function FocusArea() {
const {getActiveTab} = useActiveReplayTab();
export default function FocusArea({isVideoReplay}: {isVideoReplay?: boolean}) {
const {getActiveTab} = useActiveReplayTab({isVideoReplay});

if (isVideoReplay) {
return <TagPanel />;
}

switch (getActiveTab()) {
case TabKey.A11Y:
Expand Down
16 changes: 13 additions & 3 deletions static/app/views/replays/detail/layout/focusTabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,17 +68,23 @@ type Props = {
function FocusTabs({className, isVideoReplay}: Props) {
const organization = useOrganization();
const {pathname, query} = useLocation();
const {getActiveTab, setActiveTab} = useActiveReplayTab();
const {getActiveTab, setActiveTab} = useActiveReplayTab({isVideoReplay});
const activeTab = getActiveTab();
const supportedVideoTabs = [TabKey.TAGS];

const unsupportedVideoTab = tab => {
return isVideoReplay && !supportedVideoTabs.includes(tab);
};

return (
<ScrollableTabs className={className} underlined>
{Object.entries(getReplayTabs({organization, isVideoReplay})).map(([tab, label]) =>
label ? (
<ListLink
disabled={unsupportedVideoTab(tab)}
data-test-id={`replay-details-${tab}-btn`}
key={tab}
isActive={() => tab === activeTab}
isActive={() => (unsupportedVideoTab(tab) ? false : tab === activeTab)}
to={`${pathname}?${queryString.stringify({...query, t_main: tab})}`}
onClick={e => {
e.preventDefault();
Expand All @@ -90,7 +96,11 @@ function FocusTabs({className, isVideoReplay}: Props) {
});
}}
>
{label}
<Tooltip
title={unsupportedVideoTab(tab) ? t('This feature is coming soon') : null}
>
{label}
</Tooltip>
</ListLink>
) : null
)}
Expand Down
2 changes: 1 addition & 1 deletion static/app/views/replays/detail/layout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ function ReplayLayout({isVideoReplay = false}: {isVideoReplay?: boolean}) {
const focusArea = (
<FluidPanel title={<SmallMarginFocusTabs isVideoReplay={isVideoReplay} />}>
<ErrorBoundary mini>
<FocusArea />
<FocusArea isVideoReplay={isVideoReplay} />
</ErrorBoundary>
</FluidPanel>
);
Expand Down

0 comments on commit a80842e

Please sign in to comment.