Skip to content
Merged
Show file tree
Hide file tree
Changes from 118 commits
Commits
Show all changes
125 commits
Select commit Hold shift + click to select a range
e336a81
feat(replays): Enhance replay details navigation with start and end t…
jerryzhou196 Nov 3, 2025
76b424d
ref(replays): Simplify ReplayDetailsUserBadge component. Removed unus…
jerryzhou196 Nov 3, 2025
81f8b76
ref(replays): Update ReplayDetails and Breadcrumbs for improved navig…
jerryzhou196 Nov 3, 2025
0481f7e
ref(replays): Update replay navigation icons and structure
jerryzhou196 Nov 3, 2025
b92a135
ref(replays): Simplify replay time handling in ReplayTable and relate…
jerryzhou196 Nov 3, 2025
e9cf08f
remove erroneous comment
jerryzhou196 Nov 3, 2025
dda816f
Merge branch 'master' into replay-carousal
jerryzhou196 Nov 4, 2025
411821b
Merge branch 'master' into replay-carousal
jerryzhou196 Nov 5, 2025
ba35080
fix(replay-table): Enhance sorting functionality and update query par…
jerryzhou196 Nov 5, 2025
24c97a4
Merge branch 'master' into replay-carousal
jerryzhou196 Nov 5, 2025
d2ecfbf
fix(replay): fix typo in DEFAULT_SORT
jerryzhou196 Nov 5, 2025
8f60afe
Merge remote-tracking branch 'origin/master' into replay-carousal
jerryzhou196 Nov 6, 2025
7a46ed8
refactor(replayTable): Rename 'start' to 'end' for replay timestamps
jerryzhou196 Nov 6, 2025
0b6ba8d
fix(replayTable): Update comment for sort query string handling
jerryzhou196 Nov 6, 2025
8383216
feat(replayDetails): remove location.query
jerryzhou196 Nov 6, 2025
d70cc2d
refactor(replayTable): Remove unused end timestamp and update query h…
jerryzhou196 Nov 6, 2025
6277a38
added left margin to buttons
jerryzhou196 Nov 7, 2025
f5f3700
address Billy's code review
jerryzhou196 Nov 7, 2025
40be3b2
feat(replayTable): Integrate EventView into ReplayTable and related c…
jerryzhou196 Nov 7, 2025
d2f35ac
fix(replayDetails): Correct nextReplay calculation to handle edge cas…
jerryzhou196 Nov 7, 2025
00a8a90
feat(replayTable): normalize eventView handling in ReplayTable and co…
jerryzhou196 Nov 7, 2025
3db7bba
feat(replayTable): Enhance eventView query handling with stats period…
jerryzhou196 Nov 7, 2025
ab71b4c
Merge branch 'master' into replay-carousal
jerryzhou196 Nov 7, 2025
1ab7a54
removed changes for issueDetail Column view
jerryzhou196 Nov 7, 2025
8d8da21
undo replayController
jerryzhou196 Nov 7, 2025
c5ae428
Merge branch 'master' into replay-carousal
jerryzhou196 Nov 7, 2025
40b2262
remove export
jerryzhou196 Nov 7, 2025
a2646bb
fix(replayTable): Refactor query generation to include playlist start…
jerryzhou196 Nov 7, 2025
3c2e433
feat(replayDetails): move hover state to only be in copy button for r…
jerryzhou196 Nov 7, 2025
525f5d8
fix(replayTable): move sort fowarding back to index page
jerryzhou196 Nov 7, 2025
afab360
fix(replayTable): move sort fowarding back to index page
jerryzhou196 Nov 8, 2025
1682740
feat(replay): conditionally render if playlIstStart and playlistEnd a…
jerryzhou196 Nov 8, 2025
c0c6c01
fix(replay): refactor query handling in ReplaySessionColumn and Repla…
jerryzhou196 Nov 8, 2025
cc6b7d0
fix(replayDetails): conditionally render playlistView buttons
jerryzhou196 Nov 8, 2025
f5347d6
fix(replaySessionColumn): enhance query handling to include cursor fr…
jerryzhou196 Nov 8, 2025
89e9577
fix(groupReplays.spec): update expected query, replacing statsPeriod …
jerryzhou196 Nov 8, 2025
e4d9d75
Merge branch 'master' into replay-carousal
jerryzhou196 Nov 8, 2025
6561e90
chore(replay): Update icon for next breadcrumb button from IconNext t…
jerryzhou196 Nov 8, 2025
f29f1e4
Revert "removed changes for issueDetail Column view"
jerryzhou196 Nov 8, 2025
c77309d
fix(replaySessionColumn): refactor query construction to ensure sort …
jerryzhou196 Nov 8, 2025
24a0efa
feat(replayIndexTable): integrate eventView from location for enhance…
jerryzhou196 Nov 8, 2025
bdb0177
fix(replaySessionColumn): streamline cursor assignment in query const…
jerryzhou196 Nov 8, 2025
16ca1f2
feat(transactionReplays): add eventView prop from /insights/frontend/…
jerryzhou196 Nov 8, 2025
0d4f502
Merge remote-tracking branch 'origin/master' into replay-carousal
jerryzhou196 Nov 8, 2025
46342f9
Merge branch 'replay-carousal' into replay-carousal-issue-details
jerryzhou196 Nov 8, 2025
4bfb035
fix(transactionReplays): update expected query to include playlistSta…
jerryzhou196 Nov 9, 2025
14d3654
Merge branch 'replay-carousal' into replay-carousal-issue-details
jerryzhou196 Nov 9, 2025
6dcffb4
fix(tests): update expected query in GroupReplays and TransactionRepl…
jerryzhou196 Nov 9, 2025
c09d6e6
feat(replay): introduce useReplayPlaylist hook for managing replay pl…
jerryzhou196 Nov 9, 2025
21ed4b8
refactor(replayDetails): streamline breadcrumb component by moving re…
jerryzhou196 Nov 9, 2025
cb30e23
refactor(useReplayPlaylist): simplify query options by removing unnec…
jerryzhou196 Nov 9, 2025
3a20fb7
feat(replay): integrate ReplayPlaylistProvider into ReplayDetails for…
jerryzhou196 Nov 9, 2025
b6e532f
Merge branch 'replay-carousal' into replay-carousal-issue-details
jerryzhou196 Nov 9, 2025
47e4fe3
fix(replay): fix query property in transactions
jerryzhou196 Nov 10, 2025
cb5cbfd
Merge branch 'master' into fix-fetch-replay-list-hook
jerryzhou196 Nov 10, 2025
a664264
Merge branch 'fix-fetch-replay-list-hook' into replay-carousal
jerryzhou196 Nov 10, 2025
dd12572
refactor(replay): update replay query handling and remove unused useR…
jerryzhou196 Nov 10, 2025
30011c5
refactor(replay): update field mapping in ReplaySessionColumn for imp…
jerryzhou196 Nov 10, 2025
353f170
fix(replay): Add enabled option to useReplayList and adjust fetching …
jerryzhou196 Nov 10, 2025
ee88392
fix(replay): streamline saved query creation in useReplaysFromTransac…
jerryzhou196 Nov 10, 2025
108f0d5
Merge branch 'fix-fetch-replay-list-hook' into replay-carousal
jerryzhou196 Nov 10, 2025
5bf9e79
Merge branch 'master' into replay-carousal
jerryzhou196 Nov 10, 2025
a770c0c
Merge branch 'master' into fix-fetch-replay-list-hook
jerryzhou196 Nov 10, 2025
649918f
fix(replay): set default value for enabled option in useReplayList hook
jerryzhou196 Nov 10, 2025
aac8f09
refactor(transactionReplays): simplify empty state test by removing r…
jerryzhou196 Nov 10, 2025
5218eb6
Merge branch 'master' into fix-fetch-replay-list-hook
jerryzhou196 Nov 10, 2025
fb7722f
Merge branch 'master' into fix-fetch-replay-list-hook
jerryzhou196 Nov 10, 2025
c2be95b
Merge branch 'fix-fetch-replay-list-hook' into replay-carousal-issue-…
jerryzhou196 Nov 10, 2025
ab5c5d2
Merge branch 'fix-fetch-replay-list-hook' into replay-carousal
jerryzhou196 Nov 10, 2025
392ef16
Merge branch 'replay-carousal' into replay-carousal-issue-details
jerryzhou196 Nov 10, 2025
7c3a89a
refactor(replayTableColumns): simplify query string generation by ren…
jerryzhou196 Nov 10, 2025
72614f1
move replayPrev and replayNext icon to left of icons
jerryzhou196 Nov 11, 2025
1c71557
Merge branch 'replay-carousal' into replay-carousal-issue-details
jerryzhou196 Nov 11, 2025
5185e60
Merge branch 'replay-fix-api-doc-typo' into replay-carousal-issue-det…
jerryzhou196 Nov 11, 2025
25cbaaa
Merge branch 'master' into fix-fetch-replay-list-hook
jerryzhou196 Nov 11, 2025
f9aabfa
fix(replays): Ensure replay list fetching is correctly enabled
jerryzhou196 Nov 11, 2025
1f8ba92
fix(replays): Simplify enabled flag condition for fetching replays
jerryzhou196 Nov 11, 2025
b714401
Merge branch 'master' into fix-fetch-replay-list-hook
jerryzhou196 Nov 11, 2025
dab5a78
Merge branch 'master' into replay-carousal
jerryzhou196 Nov 11, 2025
4c03a95
Merge branch 'master' into replay-carousal
jerryzhou196 Nov 11, 2025
9864b58
Merge branch 'master' into replay-carousal-issue-details
jerryzhou196 Nov 11, 2025
01ab6c3
fix(replays): Update query parameters in tests and enable replay list…
jerryzhou196 Nov 11, 2025
7deb031
fix(replays): Update replay list fetching condition
jerryzhou196 Nov 12, 2025
18a2e93
refactor(replays): Enhance replay query handling and type definitions
jerryzhou196 Nov 12, 2025
92e9e4a
Merge branch master into replay-carousal
jerryzhou196 Nov 12, 2025
4860a30
fixed tests
jerryzhou196 Nov 12, 2025
3c093c9
ref(replays): Update sorting logic to use shared constant for replay …
jerryzhou196 Nov 12, 2025
a567e2c
ref(replays): Refactor query handling in ReplayDetailsProviders
jerryzhou196 Nov 12, 2025
989b379
ref(location): Change DefaultQuery type to local scope in useLocation…
jerryzhou196 Nov 12, 2025
164a2b2
ref(replays): Simplify query object construction in ReplayDetailsProv…
jerryzhou196 Nov 12, 2025
0fc2f4a
ref(replays): Use useRef for initial location in ReplayDetailsPageBre…
jerryzhou196 Nov 13, 2025
6efdbb3
ref(replays): Refactor ReplayDetailsPageBreadcrumbs for improved styling
jerryzhou196 Nov 13, 2025
6f21136
ref(replays): Update queryReferrer in ReplayDetailsProviders for cons…
jerryzhou196 Nov 13, 2025
c203a34
Merge branch replay-carousal into replay-carousal-issue-details
jerryzhou196 Nov 13, 2025
82ce0cc
ref(replays): Integrate EventView into ReplayPreviewPlayer and refact…
jerryzhou196 Nov 13, 2025
47d5c55
ref(replays): Enhance query handling in ReplaySessionColumn and Repla…
jerryzhou196 Nov 13, 2025
0e36592
ref(replays): Simplify sorting logic in ReplayDetailsProviders
jerryzhou196 Nov 13, 2025
5c130e6
ref(replays): Rename StyledDiv to ShortId for clarity in ReplayDetail…
jerryzhou196 Nov 13, 2025
302d359
ref(replays): Adjust sorting logic in ReplayDetailsProviders for clarity
jerryzhou196 Nov 13, 2025
d42da0d
ref(replays): Improve sorting logic in ReplayDetailsProviders for bet…
jerryzhou196 Nov 13, 2025
d1aa45a
ref(replays): Enhance parseStatsPeriod function to support UTC option
jerryzhou196 Nov 13, 2025
e03e05d
ref(replays): Clarify comment in ReplaySessionColumn regarding query …
jerryzhou196 Nov 13, 2025
ee068b7
Merge branch replay-carousal into replay-carousal-issue-details
jerryzhou196 Nov 13, 2025
3bbb027
Merge branch 'master' into replay-carousal-issue-details
jerryzhou196 Nov 14, 2025
b539b77
undo api.md change
jerryzhou196 Nov 14, 2025
a845f04
fix(replay): Update query string generation and enable flag in Replay…
jerryzhou196 Nov 14, 2025
f502fff
fix(replay): Refactor query string generation to include playlist sta…
jerryzhou196 Nov 14, 2025
5c0ebff
fix(replay): Update enabled flag logic in ReplayDetailsProviders to d…
jerryzhou196 Nov 14, 2025
e01318f
fix(replay): move to usePlaylistQuery hook to reduce eventView constr…
jerryzhou196 Nov 16, 2025
621f197
fix(replay): Add type import for EventView in groupReplaysPlayer comp…
jerryzhou196 Nov 16, 2025
0dca186
fix(replay): Make eventView optional in ReplayPreviewPlayer component…
jerryzhou196 Nov 16, 2025
f6f7ab2
refactor(replays): replace ReplayListQueryReferrer type with a const …
jerryzhou196 Nov 17, 2025
44191f2
Merge branch 'master' into replay-carousal-issue-details
jerryzhou196 Nov 17, 2025
0577fe3
feat(replay): add referrer to query parameters in ReplayDetailsProviders
jerryzhou196 Nov 17, 2025
42fdaeb
fix(replay): update query parameters in replay tests for improved acc…
jerryzhou196 Nov 17, 2025
1a9cf9a
fix(replay): make eventView prop optional in GroupReplaysPlayer compo…
jerryzhou196 Nov 17, 2025
c199673
Merge branch 'query-referrer-enum' into replay-carousal-issue-details
jerryzhou196 Nov 17, 2025
62a3367
fix(replay): update queryReferrer handling in ReplayDetailsProviders …
jerryzhou196 Nov 17, 2025
0b08236
refactor(replay): replace const array with union type for ReplayListQ…
jerryzhou196 Nov 17, 2025
fb6c831
refactor(replay): update Replay components to use query prop instead …
jerryzhou196 Nov 17, 2025
802e954
refactor(replay): extract unused field from eventView query to improv…
jerryzhou196 Nov 17, 2025
ae6a296
refactor(replay): simplify query parameters in tests and components f…
jerryzhou196 Nov 17, 2025
8bc2f62
fix(replay): handle undefined query.referrer in ReplayDetailsProvider…
jerryzhou196 Nov 17, 2025
fd0abf5
refactor(replay): streamline query parameters in usePlaylistQuery and…
jerryzhou196 Nov 17, 2025
3ee47f2
removed feedback type
jerryzhou196 Nov 18, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const mockReplayId = '761104e184c64d439ee1014b72b4d83b';
const mockEventTimestamp = new Date('2022-09-22T16:59:41Z');
const mockEventTimestampMs = mockEventTimestamp.getTime();

const mockButtonHref = `/organizations/${mockOrgSlug}/explore/replays/761104e184c64d439ee1014b72b4d83b/?referrer=%2Forganizations%2F%3AorgId%2Fissues%2F%3AgroupId%2Freplays%2F&t=57&t_main=errors`;
const mockButtonHref = `/organizations/${mockOrgSlug}/explore/replays/761104e184c64d439ee1014b72b4d83b/?playlistEnd=2017-10-17T02%3A41%3A20&playlistStart=2017-10-03T02%3A41%3A20&query=&referrer=%2Forganizations%2F%3AorgId%2Fissues%2F%3AgroupId%2Freplays%2F&t=57&t_main=errors&yAxis=count%28%29`;

// Get replay data with the mocked replay reader params
const mockReplay = ReplayReader.factory({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@ import ReplayPlayPauseButton from 'sentry/components/replays/replayPlayPauseButt
import {ReplaySidebarToggleButton} from 'sentry/components/replays/replaySidebarToggleButton';
import {ReplaySessionColumn} from 'sentry/components/replays/table/replayTableColumns';
import TimeAndScrubberGrid from 'sentry/components/replays/timeAndScrubberGrid';
import {usePlaylistQuery} from 'sentry/components/replays/usePlaylistQuery';
import {IconNext, IconPrevious} from 'sentry/icons';
import {t} from 'sentry/locale';
import {space} from 'sentry/styles/space';
import type EventView from 'sentry/utils/discover/eventView';
import getRouteStringFromRoutes from 'sentry/utils/getRouteStringFromRoutes';
import {TabKey} from 'sentry/utils/replays/hooks/useActiveReplayTab';
import useMarkReplayViewed from 'sentry/utils/replays/hooks/useMarkReplayViewed';
Expand All @@ -38,6 +40,7 @@ import {makeReplaysPathname} from 'sentry/views/replays/pathnames';
import type {ReplayListRecord, ReplayRecord} from 'sentry/views/replays/types';

export default function ReplayPreviewPlayer({
eventView,
errorBeforeReplayStart,
replayId,
fullReplayButtonProps,
Expand All @@ -51,6 +54,7 @@ export default function ReplayPreviewPlayer({
errorBeforeReplayStart: boolean;
replayId: string;
replayRecord: ReplayRecord;
eventView?: EventView;
fullReplayButtonProps?: Partial<Omit<LinkButtonProps, 'external'>>;
handleBackClick?: () => void;
handleForwardClick?: () => void;
Expand Down Expand Up @@ -89,6 +93,8 @@ export default function ReplayPreviewPlayer({
}
}, [isFetching, isPlaying, markAsViewed, organization, replayRecord]);

const playlistQuery = usePlaylistQuery(eventView);

return (
<PlayerPanel>
{errorBeforeReplayStart && (
Expand All @@ -100,6 +106,7 @@ export default function ReplayPreviewPlayer({
)}
<HeaderWrapper>
<ReplaySessionColumn.Component
query={playlistQuery}
replay={replayRecord as ReplayListRecord}
rowIndex={0}
columnIndex={0}
Expand All @@ -117,6 +124,7 @@ export default function ReplayPreviewPlayer({
t_main: fromFeedback ? TabKey.BREADCRUMBS : TabKey.ERRORS,
t: (currentTime + startOffsetMs) / 1000,
groupId,
...playlistQuery,
},
}}
{...fullReplayButtonProps}
Expand Down
6 changes: 6 additions & 0 deletions static/app/components/replays/table/replayTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ import InteractionStateLayer from 'sentry/components/core/interactionStateLayer'
import LoadingIndicator from 'sentry/components/loadingIndicator';
import type {ReplayTableColumn} from 'sentry/components/replays/table/replayTableColumns';
import ReplayTableHeader from 'sentry/components/replays/table/replayTableHeader';
import {usePlaylistQuery} from 'sentry/components/replays/usePlaylistQuery';
import {SimpleTable} from 'sentry/components/tables/simpleTable';
import {t} from 'sentry/locale';
import type EventView from 'sentry/utils/discover/eventView';
import type {Sort} from 'sentry/utils/discover/fields';
import type RequestError from 'sentry/utils/requestError/requestError';
import {ERROR_MAP} from 'sentry/utils/requestError/requestError';
Expand All @@ -26,10 +28,12 @@ type Props = SortProps & {
isPending: boolean;
replays: ReplayListRecord[];
showDropdownFilters: boolean;
eventView?: EventView;
ref?: RefObject<HTMLDivElement | null>;
};

export default function ReplayTable({
eventView,
columns,
error,
isPending,
Expand All @@ -41,6 +45,7 @@ export default function ReplayTable({
}: Props) {
const gridTemplateColumns = columns.map(col => col.width ?? 'max-content').join(' ');
const hasInteractiveColumn = columns.some(col => col.interactive);
const playlistQuery = usePlaylistQuery(eventView);

if (isPending) {
return (
Expand Down Expand Up @@ -110,6 +115,7 @@ export default function ReplayTable({
{columns.map((column, columnIndex) => (
<RowCell key={`${replay.id}-${columnIndex}-${column.sortKey}`}>
<column.Component
query={playlistQuery}
columnIndex={columnIndex}
replay={replay}
rowIndex={rowIndex}
Expand Down
52 changes: 18 additions & 34 deletions static/app/components/replays/table/replayTableColumns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import NumericDropdownFilter from 'sentry/components/replays/table/filters/numer
import OSBrowserDropdownFilter from 'sentry/components/replays/table/filters/osBrowserDropdownFilter';
import ScoreBar from 'sentry/components/scoreBar';
import {SimpleTable} from 'sentry/components/tables/simpleTable';
import {parseStatsPeriod} from 'sentry/components/timeRangeSelector/utils';
import {IconNot} from 'sentry/icons';
import {IconCursorArrow} from 'sentry/icons/iconCursorArrow';
import {IconFire} from 'sentry/icons/iconFire';
Expand All @@ -27,7 +26,6 @@ import {IconPlay} from 'sentry/icons/iconPlay';
import {t, tct} from 'sentry/locale';
import {space} from 'sentry/styles/space';
import {trackAnalytics} from 'sentry/utils/analytics';
import EventView from 'sentry/utils/discover/eventView';
import {spanOperationRelativeBreakdownRenderer} from 'sentry/utils/discover/fieldRenderers';
import getRouteStringFromRoutes from 'sentry/utils/getRouteStringFromRoutes';
import {useListItemCheckboxContext} from 'sentry/utils/list/useListItemCheckboxState';
Expand Down Expand Up @@ -58,6 +56,7 @@ interface CellProps {
replay: ListRecord;
rowIndex: number;
showDropdownFilters: boolean;
query?: Query;
}

export interface ReplayTableColumn {
Expand Down Expand Up @@ -316,10 +315,23 @@ export const ReplayDetailsLinkColumn: ReplayTableColumn = {
Header: '',
interactive: true,
sortKey: undefined,
Component: ({replay}) => {
Component: ({replay, query}) => {
const organization = useOrganization();
const replayDetailsPathname = makeReplaysPathname({
path: `/${replay.id}/`,
organization,
});

const routes = useRoutes();
const referrer = getRouteStringFromRoutes(routes);

const detailsTab = () => ({
pathname: replayDetailsPathname,
query: {referrer, ...query},
});

return (
<DetailsLink to={makeReplaysPathname({path: `/${replay.id}/`, organization})}>
<DetailsLink to={detailsTab()}>
<Tooltip title={t('See Full Replay')}>
<IconOpen />
</Tooltip>
Expand Down Expand Up @@ -507,9 +519,8 @@ export const ReplaySessionColumn: ReplayTableColumn = {
interactive: true,
sortKey: 'started_at',
width: 'minmax(150px, 1fr)',
Component: ({replay}) => {
Component: ({replay, query}) => {
const routes = useRoutes();
const location = useLocation();
const organization = useOrganization();
const project = useProjectFromId({project_id: replay.project_id ?? undefined});

Expand All @@ -523,38 +534,11 @@ export const ReplaySessionColumn: ReplayTableColumn = {
);

const referrer = getRouteStringFromRoutes(routes);
const eventView = EventView.fromLocation(location);

const {statsPeriod, start, end, ...eventViewQuery} =
eventView.generateQueryStringObject();

const detailsTabQuery: Query = {
referrer,
...eventViewQuery,
...query,
};

if (typeof statsPeriod === 'string') {
const {start: playlistStart, end: playlistEnd} = parseStatsPeriod(
statsPeriod,
undefined,
true
);
detailsTabQuery.playlistStart = playlistStart;
detailsTabQuery.playlistEnd = playlistEnd;
} else if (start && end) {
detailsTabQuery.playlistStart = start;
detailsTabQuery.playlistEnd = end;
}

// Because the sort and cursor field is only generated in EventView conditionally and we
// want to avoid dirtying the URL with fields, we manually add them to the query here.
if (location.query.sort) {
detailsTabQuery.playlistSort = location.query.sort;
}
if (location.query.cursor) {
detailsTabQuery.cursor = location.query.cursor;
}

const replayDetailsPathname = makeReplaysPathname({
path: `/${replay.id}/`,
organization,
Expand Down
37 changes: 37 additions & 0 deletions static/app/components/replays/usePlaylistQuery.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import type {Query} from 'history';

import {parseStatsPeriod} from 'sentry/components/timeRangeSelector/utils';
import EventView from 'sentry/utils/discover/eventView';
import {useLocation} from 'sentry/utils/useLocation';

export function usePlaylistQuery(eventView?: EventView): Query {
const location = useLocation();
if (!eventView) {
eventView = EventView.fromLocation(location);
}
const {statsPeriod, start, end, ...eventViewQuery} =
eventView.generateQueryStringObject();

if (typeof statsPeriod === 'string') {
const {start: playlistStart, end: playlistEnd} = parseStatsPeriod(
statsPeriod,
undefined,
true
);
eventViewQuery.playlistStart = playlistStart;
eventViewQuery.playlistEnd = playlistEnd;
} else if (start && end) {
eventViewQuery.playlistStart = start;
eventViewQuery.playlistEnd = end;
}

// Because the sort and cursor field is only generated in EventView conditionally and we
// want to avoid dirtying the URL with fields, we manually add them to the query here.
if (location.query.sort) {
eventViewQuery.playlistSort = location.query.sort;
}
if (location.query.cursor) {
eventViewQuery.cursor = location.query.cursor;
}
return eventViewQuery;
}
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ describe('GroupReplays', () => {
expect(await screen.findAllByText('testDisplayName')).toHaveLength(2);

const expectedQuery =
'playlistEnd=2022-09-28T23%3A29%3A13&playlistStart=2022-09-14T23%3A29%3A13&query=&referrer=%2Forganizations%2F%3AorgId%2Fissues%2F%3AgroupId%2Freplays%2F&yAxis=count%28%29';
'field=activity&field=browser.name&field=browser.version&field=count_dead_clicks&field=count_errors&field=count_infos&field=count_rage_clicks&field=count_segments&field=count_urls&field=count_warnings&field=device.brand&field=device.family&field=device.model_id&field=device.name&field=dist&field=duration&field=environment&field=error_ids&field=finished_at&field=has_viewed&field=id&field=info_ids&field=is_archived&field=os.name&field=os.version&field=platform&field=project_id&field=releases&field=sdk.name&field=sdk.version&field=started_at&field=tags&field=trace_ids&field=urls&field=user&field=warning_ids&id=&name=&playlistEnd=2022-09-28T23%3A29%3A13&playlistStart=2022-06-30T23%3A29%3A13&query=id%3A%5B346789a703f6454384f1de473b8b9fcc%2Cb05dae9b6be54d21a4d5ad9f8f02b780%5D&referrer=%2Forganizations%2F%3AorgId%2Fissues%2F%3AgroupId%2Freplays%2F&sort=-started_at&yAxis=count%28%29';

// Expect the first row to have the correct href
expect(
Expand Down
5 changes: 5 additions & 0 deletions static/app/views/issueDetails/groupReplays/groupReplays.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -165,12 +165,14 @@ export default function GroupReplays({group}: Props) {

function SelectedReplayWrapper({
children,
eventView,
group,
replaySlug,
overlayContent,
replays,
}: {
children: React.ReactNode;
eventView: EventView;
group: Group;
overlayContent: React.ReactNode;
replaySlug: string;
Expand All @@ -195,6 +197,7 @@ function SelectedReplayWrapper({
autoStart
>
<GroupReplaysPlayer
eventView={eventView}
replayReaderResult={readerResult}
overlayContent={overlayContent}
handleForwardClick={
Expand Down Expand Up @@ -245,6 +248,7 @@ function GroupReplaysTable({

const replayTable = (
<ReplayTable
eventView={eventView}
columns={[
...(selectedReplay ? [ReplayPlayPauseColumn] : []),
...(allMobileProj ? VISIBLE_COLUMNS_MOBILE : VISIBLE_COLUMNS),
Expand All @@ -265,6 +269,7 @@ function GroupReplaysTable({
group={group}
replaySlug={selectedReplay.id}
replays={replays}
eventView={eventView}
>
{replayTable}
</SelectedReplayWrapper>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import LoadingIndicator from 'sentry/components/loadingIndicator';
import ArchivedReplayAlert from 'sentry/components/replays/alerts/archivedReplayAlert';
import ReplayLoadingState from 'sentry/components/replays/player/replayLoadingState';
import {t} from 'sentry/locale';
import type EventView from 'sentry/utils/discover/eventView';
import type useLoadReplayReader from 'sentry/utils/replays/hooks/useLoadReplayReader';
import useLogEventReplayStatus from 'sentry/utils/replays/hooks/useLogEventReplayStatus';
import {ReplayPlayerPluginsContextProvider} from 'sentry/utils/replays/playback/providers/replayPlayerPluginsContext';
Expand All @@ -21,10 +22,12 @@ interface Props {
handleForwardClick: undefined | (() => void);
overlayContent: React.ReactNode;
replayReaderResult: ReturnType<typeof useLoadReplayReader>;
eventView?: EventView;
}

export default function GroupReplaysPlayer({
analyticsContext,
eventView,
handleForwardClick,
handleBackClick,
overlayContent,
Expand Down Expand Up @@ -65,6 +68,7 @@ export default function GroupReplaysPlayer({
<ReplayReaderProvider replay={replay}>
<ReplayPlayerStateContextProvider>
<ReplayPreviewPlayer
eventView={eventView}
errorBeforeReplayStart={replay.getErrorBeforeReplayStart()}
replayId={replayReaderResult.replayId}
replayRecord={replayReaderResult.replayRecord!}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ describe('TransactionReplays', () => {
expect(screen.getAllByText('testDisplayName')).toHaveLength(2);

const expectedQuery =
'playlistEnd=2022-09-28T23%3A29%3A13&playlistStart=2022-09-14T23%3A29%3A13&project=1&query=test&referrer=replays%2F&yAxis=count%28%29';
'field=activity&field=browser.name&field=browser.version&field=count_dead_clicks&field=count_errors&field=count_infos&field=count_rage_clicks&field=count_segments&field=count_urls&field=count_warnings&field=device.brand&field=device.family&field=device.model_id&field=device.name&field=dist&field=duration&field=environment&field=error_ids&field=finished_at&field=has_viewed&field=id&field=info_ids&field=is_archived&field=os.name&field=os.version&field=platform&field=project_id&field=releases&field=sdk.name&field=sdk.version&field=started_at&field=tags&field=trace_ids&field=urls&field=user&field=warning_ids&id=&name=&playlistEnd=2022-09-28T23%3A29%3A13&playlistStart=2022-09-14T23%3A29%3A13&query=test&referrer=replays%2F&sort=-started_at&yAxis=count%28%29';
// Expect the first row to have the correct href
expect(
screen.getByRole('link', {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ function ReplaysContent({
return (
<Layout.Main width="full">
<ReplayTable
eventView={eventView}
columns={[
ReplaySessionColumn,
...(hasRoomForColumns ? [ReplaySlowestTransactionColumn] : []),
Expand Down
15 changes: 13 additions & 2 deletions static/app/views/replays/detail/body/replayDetailsProviders.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ import type ReplayReader from 'sentry/utils/replays/replayReader';
import useLocationQuery from 'sentry/utils/url/useLocationQuery';
import useOrganization from 'sentry/utils/useOrganization';
import {ReplaySummaryContextProvider} from 'sentry/views/replays/detail/ai/replaySummaryContext';
import {type ReplayListRecord} from 'sentry/views/replays/types';
import {
REPLAY_LIST_QUERY_REFERRERS,
type ReplayListQueryReferrer,
type ReplayListRecord,
} from 'sentry/views/replays/types';

interface Props {
children: ReactNode;
Expand Down Expand Up @@ -59,6 +63,7 @@ export default function ReplayDetailsProviders({children, replay, projectSlug}:
playlistEnd: decodeScalar,
playlistSort: decodeScalar,
sort: decodeScalar,
referrer: decodeScalar,
},
});

Expand All @@ -71,10 +76,16 @@ export default function ReplayDetailsProviders({children, replay, projectSlug}:
query.sort =
!playlistSort || playlistSort === '' ? DEFAULT_REPLAY_LIST_SORT : playlistSort;

const queryReferrer = REPLAY_LIST_QUERY_REFERRERS.includes(
query.referrer as ReplayListQueryReferrer
)
? (query.referrer as ReplayListQueryReferrer)
: 'replayList';

const queryKey = useReplayListQueryKey({
options: {query},
organization,
queryReferrer: 'replaysPlayList',
queryReferrer,
});
const {data} = useApiQuery<{
data: ReplayListRecord[];
Expand Down
12 changes: 7 additions & 5 deletions static/app/views/replays/types.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -200,11 +200,13 @@ export type ReplayListLocationQuery = {
utc?: 'true' | 'false';
};

export type ReplayListQueryReferrer =
| 'replayList'
| 'issueReplays'
| 'transactionReplays'
| 'replaysPlayList';
export const REPLAY_LIST_QUERY_REFERRERS = [
'replayList',
'issueReplays',
'transactionReplays',
] as const;

export type ReplayListQueryReferrer = (typeof REPLAY_LIST_QUERY_REFERRERS)[number];

// Sync with ReplayListRecord below
// Skip some fields because the backend doesn't support them in the field list:
Expand Down
Loading