Skip to content

Commit f781be5

Browse files
michellewzhangandrewshie-sentry
authored andcommitted
ref(project): use hasFlags flag for CTA check (#83282)
use the newly implemented `hasFlags` project flag as the final layer to determine whether the CTA should be shown. ## TLDR: the CTA only shows up if... project has never sent flags before, `event.contexts.flags` is undefined, the platform is correct, & the org is under the cta flag. ``` const showCTA = !project.hasFlags && !hasFlagContext && featureFlagOnboardingPlatforms.includes(project.platform ?? 'other') && organization.features.includes('feature-flag-cta'); ``` here are the following possible code paths (all are tested) ## `event.contexts.flags = [ ... ]` -> flag table rendered <img width="870" alt="SCR-20250110-nkne" src="https://github.com/user-attachments/assets/595d0e2e-8c5f-42f6-aa16-2ee5bcead68d" /> ## `event.contexts.flags = [ ]` -> empty state <img width="849" alt="SCR-20250110-nlkr" src="https://github.com/user-attachments/assets/af07507e-e177-4c73-979b-4ea652eb73c2" /> ## `event.contexts.flags = undefined` and `hasFlags = true` -> empty state <img width="849" alt="SCR-20250110-nlkr" src="https://github.com/user-attachments/assets/af07507e-e177-4c73-979b-4ea652eb73c2" /> ## `event.contexts.flags = undefined` and `hasFlags = false` and `feature-flag-cta = true` and `platform in [javascript, python]` -> CTA shown <img width="846" alt="SCR-20250110-nkul" src="https://github.com/user-attachments/assets/07e123a3-fcab-48da-acd0-62d89a9d6a6b" /> ## `event.contexts.flags = undefined` and `feature-flag-cta = true` and `platform !in [javascript, python]` -> section hidden ## `event.contexts.flags = undefined` and `feature-flag-cta = false` -> section hidden Closes getsentry/team-replay#529
1 parent c2cf739 commit f781be5

File tree

6 files changed

+37
-36
lines changed

6 files changed

+37
-36
lines changed

static/app/components/events/featureFlags/eventFeatureFlagList.spec.tsx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
MOCK_FLAGS,
1717
NO_FLAG_CONTEXT_SECTION_PROPS_CTA,
1818
NO_FLAG_CONTEXT_SECTION_PROPS_NO_CTA,
19+
NO_FLAG_CONTEXT_WITH_FLAGS_SECTION_PROPS_NO_CTA,
1920
} from 'sentry/components/events/featureFlags/testUtils';
2021

2122
// Needed to mock useVirtualizer lists.
@@ -247,6 +248,26 @@ describe('EventFeatureFlagList', function () {
247248
expect(screen.getByText('Feature Flags')).toBeInTheDocument();
248249
});
249250

251+
it('renders empty state if event.contexts.flags is not set but should not show cta - flags already sent', function () {
252+
const org = OrganizationFixture({features: ['feature-flag-cta']});
253+
254+
render(
255+
<EventFeatureFlagList {...NO_FLAG_CONTEXT_WITH_FLAGS_SECTION_PROPS_NO_CTA} />,
256+
{
257+
organization: org,
258+
}
259+
);
260+
261+
const control = screen.queryByRole('button', {name: 'Sort Flags'});
262+
expect(control).not.toBeInTheDocument();
263+
const search = screen.queryByRole('button', {name: 'Open Feature Flag Search'});
264+
expect(search).not.toBeInTheDocument();
265+
expect(screen.getByRole('button', {name: 'Set Up Integration'})).toBeInTheDocument();
266+
expect(
267+
screen.getByText('No feature flags were found for this event')
268+
).toBeInTheDocument();
269+
});
270+
250271
it('renders nothing if event.contexts.flags is not set and should not show cta - wrong platform', async function () {
251272
const org = OrganizationFixture({features: ['feature-flag-cta']});
252273

static/app/components/events/featureFlags/eventFeatureFlagList.tsx

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import {
1111
import FeatureFlagInlineCTA from 'sentry/components/events/featureFlags/featureFlagInlineCTA';
1212
import FeatureFlagSort from 'sentry/components/events/featureFlags/featureFlagSort';
1313
import {useFeatureFlagOnboarding} from 'sentry/components/events/featureFlags/useFeatureFlagOnboarding';
14-
import useIssueEvents from 'sentry/components/events/featureFlags/useIssueEvents';
1514
import {
1615
FlagControlOptions,
1716
OrderBy,
@@ -79,12 +78,6 @@ export function EventFeatureFlagList({
7978
},
8079
});
8180

82-
const {
83-
data: relatedEvents,
84-
isPending: isRelatedEventsPending,
85-
isError: isRelatedEventsError,
86-
} = useIssueEvents({issueId: group.id});
87-
8881
const {activateSidebarSkipConfigure} = useFeatureFlagOnboarding();
8982

9083
const {
@@ -105,10 +98,6 @@ export function EventFeatureFlagList({
10598
}, [isSuspectError, isSuspectPending, suspectFlags]);
10699

107100
const hasFlagContext = Boolean(event.contexts?.flags?.values);
108-
const anyEventHasContext =
109-
isRelatedEventsPending || isRelatedEventsError
110-
? false
111-
: relatedEvents.filter(e => Boolean(e.contexts?.flags?.values)).length > 0;
112101

113102
const eventFlags: Required<FeatureFlag>[] = useMemo(() => {
114103
// At runtime there's no type guarantees on the event flags. So we have to
@@ -126,8 +115,8 @@ export function EventFeatureFlagList({
126115
const hasFlags = hasFlagContext && eventFlags.length > 0;
127116

128117
const showCTA =
118+
!project.hasFlags &&
129119
!hasFlagContext &&
130-
!anyEventHasContext &&
131120
featureFlagOnboardingPlatforms.includes(project.platform ?? 'other') &&
132121
organization.features.includes('feature-flag-cta');
133122

@@ -207,8 +196,8 @@ export function EventFeatureFlagList({
207196
return <FeatureFlagInlineCTA projectId={event.projectID} />;
208197
}
209198

210-
// if contexts.flags is not set, hide the section
211-
if (!hasFlagContext) {
199+
// if contexts.flags is not set and project has not set up flags, hide the section
200+
if (!hasFlagContext && !project.hasFlags) {
212201
return null;
213202
}
214203

static/app/components/events/featureFlags/testUtils.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,16 @@ export const NO_FLAG_CONTEXT_SECTION_PROPS_CTA = {
5757
contexts: {other: {}},
5858
platform: 'javascript',
5959
}),
60-
project: ProjectFixture({platform: 'javascript'}),
60+
project: ProjectFixture({platform: 'javascript', hasFlags: false}),
61+
group: GroupFixture({platform: 'javascript'}),
62+
};
63+
64+
export const NO_FLAG_CONTEXT_WITH_FLAGS_SECTION_PROPS_NO_CTA = {
65+
event: EventFixture({
66+
id: 'abc123def456ghi789jkl',
67+
contexts: {other: {}},
68+
platform: 'javascript',
69+
}),
70+
project: ProjectFixture({platform: 'javascript', hasFlags: true}),
6171
group: GroupFixture({platform: 'javascript'}),
6272
};

static/app/components/events/featureFlags/useIssueEvents.tsx

Lines changed: 0 additions & 21 deletions
This file was deleted.

static/app/types/project.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export type Project = {
2727
hasAccess: boolean;
2828
hasCustomMetrics: boolean;
2929
hasFeedbacks: boolean;
30+
hasFlags: boolean;
3031
hasInsightsAppStart: boolean;
3132
hasInsightsAssets: boolean;
3233
hasInsightsCaches: boolean;

tests/js/fixtures/project.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export function ProjectFixture(params: Partial<Project> = {}): Project {
3434
hasMinifiedStackTrace: false,
3535
hasProfiles: false,
3636
hasReplays: false,
37+
hasFlags: false,
3738
hasSessions: false,
3839
hasMonitors: false,
3940
hasInsightsHttp: false,

0 commit comments

Comments
 (0)