Skip to content

Hid growth tab on posts when member sources disabled#25817

Merged
troyciesco merged 9 commits intomainfrom
cursor/NY-382-hide-growth-tab-disabled-4d8d
Feb 13, 2026
Merged

Hid growth tab on posts when member sources disabled#25817
troyciesco merged 9 commits intomainfrom
cursor/NY-382-hide-growth-tab-disabled-4d8d

Conversation

@prschulz
Copy link
Contributor

@prschulz prschulz commented Jan 8, 2026

Closes https://linear.app/ghost/issue/NY-382

  • The "Growth" tab in post analytics was incorrectly displayed even when the "Member Sources" setting was disabled, leading to inconsistent UI and user confusion
  • This PR conditionally hides the "Growth" tab in the post analytics header. The tab will now only be visible if the members_track_sources setting is enabled. An e2e test has been added to verify this behavior.
  • Also adds a reusable getPostDestination helper so we can link posts to the correct location based on analytics settings. For example, if there is no analytics data to display because everything is turned off and the post wasn't emailed, clicking the post should go straight to the editor.

Note

  • Conditionally render Growth: Growth tab in header and Growth section on Overview now only appear when appSettings.analytics.membersTrackSources is true.
  • Redirect safeguard: Overview auto-redirect to growth for published-only posts occurs only if Growth is available; uses replace: true.
  • Empty state: Show DisabledSourcesIndicator when Web, Newsletter, and Growth are all unavailable.
  • E2E support: Adds SettingsService.setMembersTrackSources and an e2e test verifying Growth visibility toggles when the setting is disabled/enabled.

Written by Cursor Bugbot for commit 91182d1. This will update automatically on new commits. Configure here.

@cursor
Copy link

cursor bot commented Jan 8, 2026

Cursor Agent can help with this pull request. Just @cursor in comments and I'll start working on changes in this branch.
Learn more about Cursor Agents

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 8, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • ✅ Review completed - (🔄 Check again to review again)

Walkthrough

Gates the Growth analytics UI behind appSettings.analytics.membersTrackSources: Overview conditionally renders the Growth card and shows DisabledSourcesIndicator when no sections are visible. The analytics header only adds the Growth tab when that flag is enabled. Adds SettingsService.setMembersTrackSources(enabled: boolean) and an E2E test toggling that setting. Adds getPostDestination(postId, hasEmailData, analyticsSettings) and updates stats UI to navigate to editor or analytics routes accordingly.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the primary change: conditionally hiding the Growth tab when member sources are disabled, which aligns with the main objective across multiple files.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Description check ✅ Passed The PR description clearly relates to the changeset, detailing the hiding of the Growth tab conditionally based on the members_track_sources setting and the addition of a getPostDestination helper function.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch cursor/NY-382-hide-growth-tab-disabled-4d8d

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@troyciesco troyciesco force-pushed the cursor/NY-382-hide-growth-tab-disabled-4d8d branch 2 times, most recently from d9a396b to 006913f Compare January 19, 2026 18:27
@troyciesco troyciesco changed the title Hide growth tab disabled Hid growth tab on posts when member sources disabled Jan 19, 2026
@troyciesco troyciesco marked this pull request as ready for review January 19, 2026 18:30
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

This PR is being reviewed by Cursor Bugbot

Details

Your team is on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle for each member of your team.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

if (!isPostLoading && post && isPublishedOnly(post as Post) && !appSettings?.analytics.webAnalytics) {
navigate(`/posts/analytics/${postId}/growth`);
if (!isPostLoading && post && isPublishedOnly(post as Post) && !appSettings?.analytics.webAnalytics && showGrowthSection) {
navigate(`/posts/analytics/${postId}/growth`, {replace: true});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was possible to get into a scenario where the back button "stops working", because it tries to bring you to /<postId>, which then redirects you right back to /<postId>/growth.

So with replace: true, now when you click the back button while on /<postId>/growth it'll bring you to wherever you were before, like /analytics

@troyciesco troyciesco force-pushed the cursor/NY-382-hide-growth-tab-disabled-4d8d branch from 7cb3943 to 91182d1 Compare January 26, 2026 15:02
@troyciesco troyciesco force-pushed the cursor/NY-382-hide-growth-tab-disabled-4d8d branch from 91182d1 to 0f11622 Compare February 12, 2026 18:13
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/stats/src/views/Stats/Overview/components/latest-post.tsx (1)

107-111: ⚠️ Potential issue | 🟡 Minor

Post title click still hardcodes the analytics route, bypassing the new destination logic.

The button at Line 146 correctly uses postDestination, but clicking the post title on Line 109 always navigates to /posts/analytics/${latestPostStats.id} — even when analytics are disabled and shouldGoToEditor is true. This creates an inconsistent experience where the title and button navigate to different destinations.

Proposed fix
 <div className='text-lg font-semibold leading-tighter tracking-tight hover:cursor-pointer hover:opacity-75' onClick={() => {
     if (!isLoading && latestPostStats) {
-        navigate(`/posts/analytics/${latestPostStats.id}`, {crossApp: true});
+        navigate(postDestination, {crossApp: true});
     }
 }}>
🧹 Nitpick comments (1)
apps/stats/test/unit/utils/url-helpers.test.ts (1)

328-370: Good coverage of the key scenarios.

One minor gap: there's no test for analyticsSettings === undefined with hasEmailData = true. This would confirm that email data alone is sufficient to route to analytics even when settings are missing. Consider adding it for completeness.

Suggested additional test case
         it('returns editor route when analytics settings are unavailable and the post has no email data', () => {
             const destination = getPostDestination('post-1', false, undefined);
 
             expect(destination).toBe('/editor/post/post-1');
         });
+
+        it('returns post analytics route when analytics settings are unavailable but the post has email data', () => {
+            const destination = getPostDestination('post-1', true, undefined);
+
+            expect(destination).toBe('/posts/analytics/post-1');
+        });
     });

@troyciesco troyciesco force-pushed the cursor/NY-382-hide-growth-tab-disabled-4d8d branch from 0f11622 to 5a70fc7 Compare February 12, 2026 18:28
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@e2e/tests/admin/analytics/post-analytics/overview.test.ts`:
- Around line 49-82: The test disables members tracking with
settingsService.setMembersTrackSources(false) but only re-enables it later, so
if an assertion fails the setting remains disabled and breaks other tests; wrap
the disable/enable sequence in a try/finally (or move the test into its own
test.describe with setup/teardown) so that
settingsService.setMembersTrackSources(true) is always called (and page.reload()
applied) in the finally block or afterEach hook to guarantee restoration even on
failure.

@troyciesco troyciesco force-pushed the cursor/NY-382-hide-growth-tab-disabled-4d8d branch from 78df8ba to 2f2042c Compare February 12, 2026 20:46
membersTrackSources?: boolean;
}

export const getPostDestination = (postId: string, hasEmailData: boolean, analyticsSettings?: AnalyticsSettings) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fwiw i usually use an object as the param when it's 3+ (or even 2+) but the shape of the data that gets passed in where this gets used makes it really cumbersome to read when i do that, so i went with this

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just kidding, decided to update it 😝

@troyciesco troyciesco added the ok to merge for me You can merge this on my behalf if you want. label Feb 12, 2026
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@e2e/tests/admin/analytics/post-analytics/overview.test.ts`:
- Around line 49-84: Rename the test title to follow lowercase "what is tested -
expected outcome" (e.g., "growth tab - hidden when member sources tracking
disabled") and restructure the body into clear Arrange/Act/Assert blocks:
Arrange by instantiating SettingsService(page.request) and
PostAnalyticsPage(page) and asserting the initial visible state using
postAnalyticsPage.growthButton and postAnalyticsPage.growthSection.card; Act by
calling settingsService.setMembersTrackSources(false) and await page.reload();
Assert by checking postAnalyticsPage.growthButton and
postAnalyticsPage.growthSection.card are hidden and
postAnalyticsPage.overviewButton and postAnalyticsPage.webTrafficButton remain
visible; keep the cleanup in a finally block that calls
settingsService.setMembersTrackSources(true) and page.reload(); remove inline
commentary and rely on the clear AAA structure and descriptive test name to
convey intent.

@troyciesco troyciesco force-pushed the cursor/NY-382-hide-growth-tab-disabled-4d8d branch from c8cbd13 to 758574e Compare February 12, 2026 22:53
@cmraible
Copy link
Collaborator

cmraible commented Feb 13, 2026

I think the links in top posts aren't working as expected - might be misunderstanding something though. In this scenario:

  • Publish only post
  • Member track sources = disabled
  • Web analytics = disabled

I think the link in Top Posts should go to the editor (and it looks like that's what getPostDestination() is trying to do), but for me it's still going to post analytics.

Screenshare.-.2026-02-12.5_20_34.PM.mp4

@cmraible
Copy link
Collaborator

I think the links in top posts aren't working as expected - might be misunderstanding something though. In this scenario:

* Publish only post

* Member track sources = disabled

* Web analytics = disabled

I think the link in Top Posts should go to the editor (and it looks like that's what getPostDestination() is trying to do), but for me it's still going to post analytics.

Ignore me, I didn't git pull the latest 😄

Copy link
Collaborator

@cmraible cmraible left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚢

@troyciesco troyciesco merged commit afd9bcc into main Feb 13, 2026
31 checks passed
@troyciesco troyciesco deleted the cursor/NY-382-hide-growth-tab-disabled-4d8d branch February 13, 2026 02:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ok to merge for me You can merge this on my behalf if you want.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants