Focus dashboard on Agent Network for netbird.ai signups#708
Conversation
Store the source query parameter into localStorage on app load so it survives the OIDC redirect, and add the agent_network_only account setting to the Account interface.
Add useAgentNetworkMode, which combines the deployment config flags with the account-level agent_network_only setting, and swap the UI gating call sites (navigation, route guard, control center, flow selector, providers provider, usage overview) to it. The agent-network route guard now waits for the account to load before calling notFound so accounts enabled via settings don't get a redirect flash.
Once the logged-in account is available, apply the stored netbird.ai
signup source: new accounts (signup form still pending) are updated
with agent_network_only via PUT /accounts/{id}, while stale flags from
existing accounts are discarded. The flag is only cleared after a
successful write so failures retry on the next session.
Expose the agent_network_only account setting in the Clients settings tab so users can leave (or re-enter) the focused view. Shown when the Agent Network surface is available for the account or deployment.
|
Note Reviews pausedIt 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 Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAgent Network mode now incorporates account-level settings through a shared hook. The mode controls route access, API fetching, navigation, onboarding, upgrade links, signup initialization, and a new settings toggle. ChangesAgent Network mode
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant AppLayout
participant BrowserStorage
participant NetBirdCloudProvider
participant AccountsAPI
AppLayout->>BrowserStorage: store signup_source=netbird.ai
NetBirdCloudProvider->>BrowserStorage: read signup source
NetBirdCloudProvider->>AccountsAPI: update agent_network_only
AccountsAPI-->>NetBirdCloudProvider: account response
NetBirdCloudProvider->>BrowserStorage: remove signup source
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/layouts/Navigation.tsx (1)
179-233: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winExtract the repeated
agentNetworkEnabled && permission?.services?.readcondition.The same expression is duplicated across the parent item and all 4 children. Extracting it avoids future edits accidentally diverging one occurrence from the rest.
♻️ Proposed refactor
+ {(() => { + const canAccessAgentNetwork = + agentNetworkEnabled && !!permission?.services?.read; + return ( <SidebarItem icon={<AgentNetworkIcon size={16} />} ... - visible={agentNetworkEnabled && permission?.services?.read} + visible={canAccessAgentNetwork} > <SidebarItem label="Providers" ... - visible={agentNetworkEnabled && permission?.services?.read} + visible={canAccessAgentNetwork} /> {/* ...same for Policies / Usage & Logs / Configuration */} </SidebarItem> + ); + })()}(Or, simpler, just define
const canAccessAgentNetwork = agentNetworkEnabled && !!permission?.services?.read;near the top of the component alongsideagentNetworkOnly/agentNetworkEnabledand reuse it in all 5 places.)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/layouts/Navigation.tsx` around lines 179 - 233, In the Navigation component, extract the repeated agentNetworkEnabled && permission?.services?.read expression into a shared canAccessAgentNetwork value near agentNetworkOnly and agentNetworkEnabled, then use that value for the Agent Network parent and all four child SidebarItem visible props.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/cloud/contexts/NetBirdCloudProvider.tsx`:
- Around line 54-88: The signup-source effect in NetBirdCloudProvider currently
applies agent_network_only asynchronously, allowing the regular onboarding UI to
flash before revalidation. Track whether the AGENT_NETWORK_SIGNUP_SOURCE is
being consumed and gate OnboardingProvider’s showOnboarding/rendering until
accountRequest settles or the localStorage key is removed, while preserving
normal onboarding behavior for unrelated accounts and completed or
already-configured signups.
---
Nitpick comments:
In `@src/layouts/Navigation.tsx`:
- Around line 179-233: In the Navigation component, extract the repeated
agentNetworkEnabled && permission?.services?.read expression into a shared
canAccessAgentNetwork value near agentNetworkOnly and agentNetworkEnabled, then
use that value for the Agent Network parent and all four child SidebarItem
visible props.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 25446e7c-3a47-4299-ae57-b2165859de11
📒 Files selected for processing (14)
src/app/(dashboard)/agent-network/layout.tsxsrc/app/(dashboard)/control-center/page.tsxsrc/cloud/contexts/NetBirdCloudProvider.tsxsrc/hooks/useSignupSource.tssrc/interfaces/Account.tssrc/layouts/AppLayout.tsxsrc/layouts/Navigation.tsxsrc/modules/agent-network/AIProvidersProvider.tsxsrc/modules/agent-network/AgentOverviewPanel.tsxsrc/modules/agent-network/useAgentNetworkMode.tssrc/modules/billing/trial/TrialOrUpgradeButton.tsxsrc/modules/control-center/FlowSelector.tsxsrc/modules/onboarding/OnboardingProvider.tsxsrc/modules/settings/ClientSettingsTab.tsx
Prevents the regular onboarding from flashing before agent_network_only is persisted: while a new account still carries the netbird.ai signup source and is unmarked, the focused view applies immediately. Gated on signup_form_pending so an existing user's stale source flag never flips the view.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/modules/agent-network/useAgentNetworkMode.ts`:
- Around line 16-18: Update isAgentNetworkSignupPending and the related
agent-network mode decision around isAgentNetworkOnly so an explicit
account.settings.agent_network_only === false always opts out. Use nullish
fallback semantics for optional settings, and apply signup-pending optimism only
when agent_network_only is absent, without allowing deployment configuration to
override the explicit false value.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 58b5e0dd-cd82-41c5-a542-6f6a662f650d
📒 Files selected for processing (1)
src/modules/agent-network/useAgentNetworkMode.ts
Use nullish fallback so an explicit account setting (true or false) always wins: a user can disable the focused view even when the deployment config enables it, and the signup-pending optimism only applies when the setting is absent, never overriding an explicit false.
…-source-onboarding
There was a problem hiding this comment.
🧹 Nitpick comments (2)
e2e/tests/agent-network-focused-view.spec.ts (2)
140-140: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winUse
visitByNavigationinstead of direct click for sidebar navigation.Line 140 clicks the "Agent Network" sidebar item directly via
navItem(page, "Agent Network").click(). UsevisitByNavigation(page, "Agent Network")to click sidebar items for navigation, per the test conventions.As per coding guidelines: "Use
visitByNavigation(page, navText)to click sidebar items for navigation instead of direct element selection."♻️ Proposed fix
- await navItem(page, "Agent Network").click(); + await visitByNavigation(page, "Agent Network");🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@e2e/tests/agent-network-focused-view.spec.ts` at line 140, Replace the direct sidebar click in the Agent Network navigation flow with visitByNavigation(page, "Agent Network"), preserving the existing navigation behavior and following the established test convention.Source: Coding guidelines
198-200: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winUse
page.waitForResponse()instead ofexpect.pollfor waiting on API responses.The test polls
captured.putBodyto detect the PUT request. The coding guidelines specify usingpage.waitForResponse()with timeout and method/URL matching. Since the PUT is triggered by an app effect (not a user action in the test), set up the listener before or immediately afterloginToAppto avoid missing the response.As per coding guidelines: "Use
page.waitForResponse()with timeout and method/URL matching to wait for specific API responses before assertions."♻️ Proposed fix
- // The signup source is persisted as the account setting. - await expect - .poll(() => captured.putBody?.settings?.agent_network_only) - .toBe(true); + // The signup source is persisted as the account setting. + const putResponse = await page.waitForResponse( + (response) => + response.url().includes("/api/accounts/") && + response.request().method() === "PUT", + { timeout: 15000 }, + ); + const putBody = await putResponse.request().postDataJSON(); + expect(putBody?.settings?.agent_network_only).toBe(true);🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@e2e/tests/agent-network-focused-view.spec.ts` around lines 198 - 200, Replace the expect.poll assertion on captured.putBody.settings.agent_network_only with page.waitForResponse(), configuring a timeout and matching the PUT method and expected API URL. Register the response listener before or immediately after loginToApp so the app-triggered request cannot be missed, then assert the response body or captured request data confirms agent_network_only is true.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@e2e/tests/agent-network-focused-view.spec.ts`:
- Line 140: Replace the direct sidebar click in the Agent Network navigation
flow with visitByNavigation(page, "Agent Network"), preserving the existing
navigation behavior and following the established test convention.
- Around line 198-200: Replace the expect.poll assertion on
captured.putBody.settings.agent_network_only with page.waitForResponse(),
configuring a timeout and matching the PUT method and expected API URL. Register
the response listener before or immediately after loginToApp so the
app-triggered request cannot be missed, then assert the response body or
captured request data confirms agent_network_only is true.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 8a423421-ba06-4c67-9dde-3a86144aa034
📒 Files selected for processing (1)
e2e/tests/agent-network-focused-view.spec.ts
…kend permission gaps
Await the /accounts revalidation before clearing the netbird.ai signup source key. Clearing it first left a window where neither the source-pending optimism nor the persisted agent_network_only setting held, so the focused view flipped off for a beat and tore down the onboarding form exactly as the enablement toast appeared.
The agent-network onboarding signup-form step was gated self-hosted-only, so cloud netbird.ai signups skipped it. Drive it off signup_form_pending on both cloud and self-hosted so those users fill the form and then continue through the agent-network onboarding flow.
…m flash account can load before useAgentNetworkMode's own /accounts fetch settles, which briefly rendered the regular onboarding form and then switched to the Agent Network flow. Hold onboarding while the mode is loading so the user only ever sees the correct form.
|
Note Unit test generation is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it. Generating unit tests... This may take up to 20 minutes. |
…lashes Reading the netbird.ai signup source synchronously lets onboarding commit to the Agent Network form on the first render, independent of when the account setting or agent-network mode data settles. The regular form is no longer shown to netbird.ai arrivals while the backend catches up.
|
Request timed out after 900000ms (requestId=96918499-15ad-4cb7-a9c8-2090e792b7a8) |
Adds a test-only override to render onboarding in the test build, testids on both onboarding forms, and a spec validating which form shows first and which persists: netbird.ai signup shows the Agent Network form (never the regular one, even under a slow backend), a plain cloud account shows the regular form, and an agent_network_only account shows the Agent Network form.
|
Note Unit test generation is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it. Generating unit tests... This may take up to 20 minutes. |
|
Request timed out after 900000ms (requestId=03d4487e-69a4-4b84-b1ab-45d0979f3050) |
Upstream features preserved: - Agent Network (netbirdio#684, netbirdio#708) - Lazy Connections (netbirdio#706) - New Traffic Filters (netbirdio#704) - Cluster one-click deploy (netbirdio#707) - etc. i18n preserved: - All zh.ts/en.ts keys intact - Control-center, VersionInfo, Navigation translations - Translation framework (next-intl) retained Resolved: Navigation t() definition, PeersTable types
Issue ticket number and link
Focuses the dashboard on the Agent Network surface for accounts that sign up
through netbird.ai, and takes those users through the Agent Network onboarding.
Fully user-reversible, and a no-op for every other account.
Signup source → account mark
?signup_source=netbird.aiinto localStorage so itsurvives the OIDC redirect (mirrors the AWS Marketplace capture hook).
onboarding.signup_form_pending)and not already marked, the dashboard
PUTssettings.agent_network_only=true,then awaits
/accountsrevalidation before clearing the source key (auseRefguard prevents duplicate writes). Awaiting the revalidation matters: clearing
the key earlier left a window with neither the source optimism nor the stored
setting, which briefly flipped the focused view off.
Mode resolution (backward-compatible)
useAgentNetworkMode()returns{ only, enabled, loading }using nullishsemantics: an explicit
agent_network_only(true or false) always wins, so auser can opt out even when a deployment config flag is on; when the setting is
absent, a pending netbird.ai signup (optimistic) or the existing
NETBIRD_AGENT_NETWORK_ONLY/_ENABLEDconfig decides. With no accountsetting, behavior is exactly as before — the setting is purely additive.
gates read the resolver instead of the config functions. The route guard waits
for account load to avoid a redirect flash.
Onboarding
shown on cloud, not only self-hosted) followed by the agent-network flow.
signup_sourcesynchronously at render, soa netbird.ai arrival commits to the Agent Network form on first paint and the
regular form is never shown to them, even when the backend is slow to persist
the setting.
Opt-out
settings.agent_network_only=false, which the resolver honors over any configflag.
Tests
(which form shows first / persists across signup-source and account states,
including a slow-backend case). Onboarding is disabled in the test build by
default; the specs opt in via a test-only override.
Depends on the backend
agent_network_onlysetting (netbirdio/netbird#6736).Note:
pkgsDownloadUrlstill reads the deployment config flag for the RCinstaller-channel suffix (plain utility, no hook context), so account-marked
accounts get stable installers — flagged for a follow-up if RC is desired there.
Documentation
Select exactly one:
The focused dashboard view and its Settings opt-out are documented in the docs
PR below.
Docs PR URL (required if "docs added" is checked)
Paste the PR link from https://github.com/netbirdio/docs here:
netbirdio/docs#848
E2E tests
Optional: override the image tags used by the Playwright e2e workflow.
Defaults to
mainwhen omitted.management-cloud-tag: main
reverse-proxy-tag: main
Summary by CodeRabbit
New Features
Improvements
Tests