Skip to content

Commit

Permalink
ref(replay): Move custom breadcrumbs to breadcrumb list (#77962)
Browse files Browse the repository at this point in the history
Moves custom breadcrumbs from console tab to breadcrumbs tab. They can
also be filtered in the breadcrumbs tab with `Custom`.

Before:
<img width="738" alt="image"
src="https://github.com/user-attachments/assets/19d6fff9-1952-4baf-866b-346afe1c7034">

After:
<img width="738" alt="image"
src="https://github.com/user-attachments/assets/bfc8bcc4-b08d-4897-b393-1b969aa68023">

Closes #69230 and
#71504
  • Loading branch information
c298lee committed Sep 23, 2024
1 parent 382ca4e commit acc3087
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 36 deletions.
55 changes: 30 additions & 25 deletions static/app/components/replays/breadcrumbs/breadcrumbItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {CodeSnippet} from 'sentry/components/codeSnippet';
import {Flex} from 'sentry/components/container/flex';
import ErrorBoundary from 'sentry/components/errorBoundary';
import Link from 'sentry/components/links/link';
import ObjectInspector from 'sentry/components/objectInspector';
import PanelItem from 'sentry/components/panels/panelItem';
import {OpenReplayComparisonButton} from 'sentry/components/replays/breadcrumbs/openReplayComparisonButton';
import {useReplayContext} from 'sentry/components/replays/replayContext';
Expand Down Expand Up @@ -88,17 +87,19 @@ function BreadcrumbItem({
{description}
</Description>
) : (
<InspectorWrapper>
<ObjectInspector
data={description}
expandPaths={expandPaths}
onExpand={onInspectorExpanded}
theme={{
TREENODE_FONT_SIZE: '0.7rem',
ARROW_FONT_SIZE: '0.5rem',
<Wrapper>
<StructuredEventData
initialExpandedPaths={expandPaths ?? []}
onToggleExpand={(expandedPaths, path) => {
onInspectorExpanded(
path,
Object.fromEntries(expandedPaths.map(item => [item, true]))
);
}}
data={description}
withAnnotatedText
/>
</InspectorWrapper>
</Wrapper>
);
}, [description, expandPaths, onInspectorExpanded]);

Expand Down Expand Up @@ -295,17 +296,19 @@ function WebVitalData({
}

return (
<StructuredEventData
initialExpandedPaths={expandPaths ?? []}
onToggleExpand={(expandedPaths, path) => {
onInspectorExpanded(
path,
Object.fromEntries(expandedPaths.map(item => [item, true]))
);
}}
data={webVitalData}
withAnnotatedText
/>
<Wrapper>
<StructuredEventData
initialExpandedPaths={expandPaths ?? []}
onToggleExpand={(expandedPaths, path) => {
onInspectorExpanded(
path,
Object.fromEntries(expandedPaths.map(item => [item, true]))
);
}}
data={webVitalData}
withAnnotatedText
/>
</Wrapper>
);
}

Expand Down Expand Up @@ -376,10 +379,6 @@ const CrumbIssueWrapper = styled('div')`
color: ${p => p.theme.subText};
`;

const InspectorWrapper = styled('div')`
font-family: ${p => p.theme.text.familyMono};
`;

const CrumbDetails = styled('div')`
display: flex;
flex-direction: column;
Expand Down Expand Up @@ -521,4 +520,10 @@ const SelectorButton = styled(Button)`
min-height: auto;
`;

const Wrapper = styled('div')`
pre {
margin: 0;
}
`;

export default memo(BreadcrumbItem);
6 changes: 3 additions & 3 deletions static/app/utils/replays/getFrameDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -430,9 +430,9 @@ const MAPPER_FOR_FRAME: Record<string, (frame) => Details> = {

const MAPPER_DEFAULT = (frame): Details => ({
color: 'gray300',
description: frame.message ?? '',
tabKey: TabKey.CONSOLE,
title: defaultTitle(frame),
description: frame.message ?? frame.data ?? '',
tabKey: TabKey.BREADCRUMBS,
title: toTitleCase(defaultTitle(frame)),
icon: <IconTerminal size="xs" />,
});

Expand Down
10 changes: 6 additions & 4 deletions static/app/utils/replays/replayReader.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -167,10 +167,11 @@ describe('ReplayReader', () => {
},
{
method: 'getConsoleFrames',
expected: [
expect.objectContaining({category: 'console'}),
expect.objectContaining({category: 'redux.action'}),
],
expected: [expect.objectContaining({category: 'console'})],
},
{
method: 'getCustomFrames',
expected: [expect.objectContaining({category: 'redux.action'})],
},
{
method: 'getNetworkFrames',
Expand All @@ -196,6 +197,7 @@ describe('ReplayReader', () => {
expected: [
expect.objectContaining({category: 'replay.init'}),
expect.objectContaining({category: 'ui.slowClickDetected'}),
expect.objectContaining({category: 'redux.action'}),
expect.objectContaining({op: 'navigation.navigate'}), // prefer the nav span over the breadcrumb
expect.objectContaining({category: 'ui.click'}),
expect.objectContaining({category: 'ui.click'}),
Expand Down
12 changes: 8 additions & 4 deletions static/app/utils/replays/replayReader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -538,10 +538,7 @@ export default class ReplayReader {
getErrorFrames = () => this._errors;

getConsoleFrames = memoize(() =>
this._sortedBreadcrumbFrames.filter(
frame =>
frame.category === 'console' || !BreadcrumbCategories.includes(frame.category)
)
this._sortedBreadcrumbFrames.filter(frame => frame.category === 'console')
);

getNavigationFrames = memoize(() =>
Expand Down Expand Up @@ -589,11 +586,18 @@ export default class ReplayReader {
this._sortedSpanFrames.filter((frame): frame is MemoryFrame => frame.op === 'memory')
);

getCustomFrames = memoize(() =>
this._sortedBreadcrumbFrames.filter(
frame => !BreadcrumbCategories.includes(frame.category)
)
);

getChapterFrames = memoize(() =>
this._trimFramesToClipWindow(
[
...this.getPerfFrames(),
...this.getWebVitalFrames(),
...this.getCustomFrames(),
...this._sortedBreadcrumbFrames.filter(frame =>
[
'replay.hydrate-error',
Expand Down
1 change: 1 addition & 0 deletions static/app/utils/replays/types.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@ export const BreadcrumbCategories = [
'device.battery',
'device.connectivity',
'device.orientation',
'feedback',
'navigation',
'replay.init',
'replay.mutations',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ const TYPE_TO_LABEL: Record<string, string> = {
tap: 'User Tap',
device: 'Device',
app: 'App',
custom: 'Custom',
};

const OPORCATEGORY_TO_TYPE: Record<string, keyof typeof TYPE_TO_LABEL> = {
Expand Down Expand Up @@ -114,6 +115,13 @@ function useBreadcrumbFilters({frames}: Options): Return {
const type = useMemo(() => decodeList(query.f_b_type), [query.f_b_type]);
const searchTerm = decodeScalar(query.f_b_search, '').toLowerCase();

// add custom breadcrumbs to filter
frames.forEach(frame => {
if (!(getFrameOpOrCategory(frame) in OPORCATEGORY_TO_TYPE)) {
OPORCATEGORY_TO_TYPE[getFrameOpOrCategory(frame)] = 'custom';
}
});

const items = useMemo(() => {
// flips OPORCATERGORY_TO_TYPE and prevents overwriting nav entry, nav entry becomes nav: ['navigation','navigation.push']
const TYPE_TO_OPORCATEGORY = Object.entries(OPORCATEGORY_TO_TYPE).reduce(
Expand Down

0 comments on commit acc3087

Please sign in to comment.