Skip to content

Commit bc16615

Browse files
fix(replays): add prompt if user needs SDK upgrade (#53672)
fixes getsentry/team-replay#126 by informing users they need to upgrade their SDK to see rage/dead click data if this applies. no results but SDK version is good: <img width="1191" alt="SCR-20230726-ohpi" src="https://github.com/getsentry/sentry/assets/56095982/25de2c86-7598-4890-b20e-159aee87388f"> no results and SDK version too low: <img width="1106" alt="SCR-20230727-mlgz" src="https://github.com/getsentry/sentry/assets/56095982/ab1bae55-01f8-4095-b56b-cb7f4f3ebe0a"> error alert also updated: <img width="1106" alt="SCR-20230727-mlxl" src="https://github.com/getsentry/sentry/assets/56095982/23b91f87-715b-47bc-8410-552a5912fbae"> <img width="1103" alt="SCR-20230727-mmci" src="https://github.com/getsentry/sentry/assets/56095982/cbb47272-d8af-44ee-8ef7-552e467574bd">
1 parent f380060 commit bc16615

File tree

5 files changed

+63
-6
lines changed

5 files changed

+63
-6
lines changed

api-docs/dump.rdb

-21.3 KB
Binary file not shown.

static/app/views/issueDetails/groupReplays/groupReplays.spec.tsx

+5
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ function init({organizationProps = {features: ['session-replay']}}: InitializeOr
5151
describe('GroupReplays', () => {
5252
beforeEach(() => {
5353
MockApiClient.clearMockResponses();
54+
MockApiClient.addMockResponse({
55+
method: 'GET',
56+
url: `/organizations/org-slug/sdk-updates/`,
57+
body: [],
58+
});
5459
});
5560

5661
describe('Replay Feature Disabled', () => {

static/app/views/performance/transactionSummary/transactionReplays/index.spec.tsx

+5
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,11 @@ describe('TransactionReplays', () => {
8989
let eventsMockApi: jest.Mock<any, any>;
9090
let replaysMockApi: jest.Mock<any, any>;
9191
beforeEach(() => {
92+
MockApiClient.addMockResponse({
93+
method: 'GET',
94+
url: `/organizations/org-slug/sdk-updates/`,
95+
body: [],
96+
});
9297
MockApiClient.addMockResponse({
9398
url: '/organizations/org-slug/events-has-measurements/',
9499
body: {measurements: false},

static/app/views/replays/list/replaysList.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ function ReplaysListTable({
8383
const {needsUpdate: allSelectedProjectsNeedUpdates} = useProjectSdkNeedsUpdate({
8484
minVersion: MIN_REPLAY_CLICK_SDK,
8585
organization,
86-
projectId: projects.map(p => String(p)),
86+
projectId: projects.map(String),
8787
});
8888

8989
const conditions = useMemo(() => {

static/app/views/replays/replayTable/index.tsx

+52-5
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,17 @@ import styled from '@emotion/styled';
33
import {Location} from 'history';
44

55
import {Alert} from 'sentry/components/alert';
6+
import ExternalLink from 'sentry/components/links/externalLink';
67
import LoadingIndicator from 'sentry/components/loadingIndicator';
78
import PanelTable from 'sentry/components/panels/panelTable';
8-
import {t} from 'sentry/locale';
9+
import {t, tct} from 'sentry/locale';
910
import EventView from 'sentry/utils/discover/eventView';
1011
import type {Sort} from 'sentry/utils/discover/fields';
1112
import getRouteStringFromRoutes from 'sentry/utils/getRouteStringFromRoutes';
1213
import {useLocation} from 'sentry/utils/useLocation';
1314
import useOrganization from 'sentry/utils/useOrganization';
15+
import usePageFilters from 'sentry/utils/usePageFilters';
16+
import useProjectSdkNeedsUpdate from 'sentry/utils/useProjectSdkNeedsUpdate';
1417
import {useRoutes} from 'sentry/utils/useRoutes';
1518
import type {ReplayListRecordWithTx} from 'sentry/views/performance/transactionSummary/transactionReplays/useReplaysWithTxData';
1619
import HeaderCell from 'sentry/views/replays/replayTable/headerCell';
@@ -28,6 +31,8 @@ import {
2831
import {ReplayColumn} from 'sentry/views/replays/replayTable/types';
2932
import type {ReplayListRecord} from 'sentry/views/replays/types';
3033

34+
const MIN_DEAD_RAGE_CLICK_SDK = '7.60.1';
35+
3136
type Props = {
3237
fetchError: undefined | Error;
3338
isFetching: boolean;
@@ -53,6 +58,18 @@ function ReplayTable({
5358
const newLocation = useLocation();
5459
const organization = useOrganization();
5560

61+
const {
62+
selection: {projects},
63+
} = usePageFilters();
64+
65+
const needSDKUpgrade = useProjectSdkNeedsUpdate({
66+
minVersion: MIN_DEAD_RAGE_CLICK_SDK,
67+
organization,
68+
projectId: projects.map(String),
69+
});
70+
71+
const showBottomBorder = visibleColumns.includes(ReplayColumn.MOST_RAGE_CLICKS);
72+
5673
const location: Location = saveLocation
5774
? {
5875
pathname: '',
@@ -78,7 +95,7 @@ function ReplayTable({
7895
data-test-id="replay-table"
7996
gridRows={undefined}
8097
>
81-
<StyledAlert type="error" showIcon>
98+
<StyledAlert type="error" showIcon showBottomBorder={showBottomBorder}>
8299
{typeof fetchError === 'string'
83100
? fetchError
84101
: t(
@@ -89,6 +106,32 @@ function ReplayTable({
89106
);
90107
}
91108

109+
if (
110+
needSDKUpgrade.needsUpdate &&
111+
visibleColumns.includes(ReplayColumn.COUNT_DEAD_CLICKS)
112+
) {
113+
return (
114+
<StyledPanelTable
115+
headers={tableHeaders}
116+
visibleColumns={visibleColumns}
117+
data-test-id="replay-table"
118+
gridRows={undefined}
119+
loader={<LoadingIndicator style={{margin: '54px auto'}} />}
120+
disablePadding
121+
>
122+
<StyledAlert type="info" showIcon showBottomBorder={showBottomBorder}>
123+
{tct('[data] requires [sdkPrompt]. [link:Upgrade now.]', {
124+
data: <strong>Rage and dead clicks</strong>,
125+
sdkPrompt: <strong>{t('SDK version >= 7.60.1')}</strong>,
126+
link: (
127+
<ExternalLink href="https://docs.sentry.io/platforms/javascript/install/npm/" />
128+
),
129+
})}
130+
</StyledAlert>
131+
</StyledPanelTable>
132+
);
133+
}
134+
92135
const referrer = getRouteStringFromRoutes(routes);
93136
const eventView = EventView.fromLocation(location);
94137

@@ -207,14 +250,18 @@ const StyledPanelTable = styled(PanelTable)<{
207250
)
208251
.join(' ')};
209252
210-
${props => (props.gridRows ? `grid-template-rows: ${props.gridRows};` : '')}
253+
${props =>
254+
props.gridRows
255+
? `grid-template-rows: ${props.gridRows};`
256+
: `grid-template-rows: 44px max-content;`}
211257
`;
212258

213-
const StyledAlert = styled(Alert)`
259+
const StyledAlert = styled(Alert)<{showBottomBorder?: boolean}>`
214260
border-radius: 0;
215-
border-width: 1px 0 0 0;
216261
grid-column: 1/-1;
217262
margin-bottom: 0;
263+
${props =>
264+
props.showBottomBorder ? `border-width: 1px 0 1px 0;` : `border-width: 1px 0 0 0;`}
218265
`;
219266

220267
export default ReplayTable;

0 commit comments

Comments
 (0)