Skip to content

Integration detail: explain how to unlock tools when there are no connections#1264

Merged
RhysSullivan merged 1 commit into
mainfrom
ux/integration-detail-unlock-cta
Jul 2, 2026
Merged

Integration detail: explain how to unlock tools when there are no connections#1264
RhysSullivan merged 1 commit into
mainfrom
ux/integration-detail-unlock-cta

Conversation

@RhysSullivan

@RhysSullivan RhysSullivan commented Jul 2, 2026

Copy link
Copy Markdown
Collaborator

After adding an integration (for example an OpenAPI spec with 19 operations) the Tools tab showed only No tools available, with nothing telling the user that adding a connection is the missing step. The user did everything right, got a success, and the product looked broken.

With zero connections the Tools tab now shows: No tools yet / Add a connection to unlock this integration's tools, with an Add connection button that opens the same dialog as the Accounts tab.

Verified manually end to end (add spec, land on detail, follow the CTA). Typecheck is green.

Stacked on #1263.

@greptile-apps

greptile-apps Bot commented Jul 2, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds a guided empty state to the Tools tab of the integration detail page when no connections exist yet. Previously, a user who had just added an OpenAPI integration would see a generic "No tools available" message with no actionable guidance.

  • A new NoConnectionToolsEmptyState component renders "No tools yet / Add a connection to unlock this integration's tools" with an "Add connection" button that opens the existing add-connection dialog by navigating to the Accounts tab and setting a manualAccountHandoff — mirroring the URL-param handoff already used for OAuth callbacks.
  • The urlAccountHandoff / manualAccountHandoff split cleanly separates URL-driven and user-driven handoffs via a nullish-coalesce merge, with no changes to the existing URL handling logic.

Confidence Score: 5/5

The change is UI-only, narrowly scoped to the right-panel empty state in the Tools tab, with no new API calls or mutations.

The handoff mechanism mirrors the existing URL-driven path exactly, and the new conditional branch in the right panel is straightforward.

packages/react/src/pages/integration-detail.tsx — the new empty-state branch and manualAccountHandoff state are the only areas worth a second look.

Important Files Changed

Filename Overview
packages/react/src/pages/integration-detail.tsx Adds manualAccountHandoff state, splits urlAccountHandoff from the merged accountHandoff, introduces handleOpenAddConnection, and renders NoConnectionToolsEmptyState in the right panel when integrationConnections is empty for non-built-in integrations.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Tools tab right panel] --> B{selectedTool && selectedAddress && selectedBareName?}
    B -- Yes --> C[ToolDetail]
    B -- No --> D{!isBuiltInIntegration && integrationConnections.length === 0?}
    D -- Yes --> E[NoConnectionToolsEmptyState]
    E --> F{canAddConnection = accountsMethods.length > 0}
    F -- true --> G[Enabled Add connection button]
    F -- false --> H[Disabled button with no explanation]
    G --> I[handleOpenAddConnection]
    I --> J[setActiveTab accounts]
    I --> K[setManualAccountHandoff with Date.now key]
    K --> L[accountHandoff = manualAccountHandoff ?? urlAccountHandoff]
    L --> M[useEffect: setActiveTab accounts]
    L --> N[AccountsSection useEffect: setAdding true opens dialog]
    D -- No --> O[ToolDetailEmpty hasTools=integrationTools.length > 0]
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A[Tools tab right panel] --> B{selectedTool && selectedAddress && selectedBareName?}
    B -- Yes --> C[ToolDetail]
    B -- No --> D{!isBuiltInIntegration && integrationConnections.length === 0?}
    D -- Yes --> E[NoConnectionToolsEmptyState]
    E --> F{canAddConnection = accountsMethods.length > 0}
    F -- true --> G[Enabled Add connection button]
    F -- false --> H[Disabled button with no explanation]
    G --> I[handleOpenAddConnection]
    I --> J[setActiveTab accounts]
    I --> K[setManualAccountHandoff with Date.now key]
    K --> L[accountHandoff = manualAccountHandoff ?? urlAccountHandoff]
    L --> M[useEffect: setActiveTab accounts]
    L --> N[AccountsSection useEffect: setAdding true opens dialog]
    D -- No --> O[ToolDetailEmpty hasTools=integrationTools.length > 0]
Loading

Reviews (4): Last reviewed commit: "Add a tools unlock CTA for empty integra..." | Re-trigger Greptile

}
: {})}
/>
) : !isBuiltInIntegration && integrationConnections.length === 0 ? (

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Race condition: "No tools yet" flashes for users who have connections

integrationConnections falls back to [] whenever connectionsResult is not yet Success (line 219). If the tools atom resolves first — a common split-fetch scenario — the NoConnectionToolsEmptyState is momentarily rendered even for integrations with active connections. During that window the right panel shows "No tools yet / Add a connection" while the left ToolTree already displays the loaded tools, producing a confusing split-state flash. The guard needs to confirm that connectionsResult has actually loaded before trusting an empty integrationConnections.

Suggested change
) : !isBuiltInIntegration && integrationConnections.length === 0 ? (
) : !isBuiltInIntegration && AsyncResult.isSuccess(connectionsResult) && integrationConnections.length === 0 ? (

Comment on lines +345 to +348
const handleOpenAddConnection = () => {
setActiveTab("accounts");
setManualAccountHandoff({ key: `manual:${String(slug)}:${Date.now()}` });
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Stale manualAccountHandoff can re-open the dialog after dismissal

handleOpenAddConnection sets manualAccountHandoff with a Date.now() key, but it is never reset to null after the user dismisses the dialog. AccountsSection calls setAdding(true) inside a useEffect([accountHandoff]), so any future re-mount of the Accounts panel (e.g. due to a parent re-render that drops and recreates the TabsContent subtree) would fire that effect again with the stale handoff and reopen the modal unexpectedly. Clearing manualAccountHandoff when the user leaves the Accounts dialog — or at minimum after the tab switch completes — would prevent this.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 2, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
executor-marketing b0037e9 Commit Preview URL

Branch Preview URL
Jul 02 2026, 08:02 PM

@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Cloudflare preview

Torn down — the PR is closed.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 2, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
executor-cloud b0037e9 Jul 02 2026, 08:02 PM

@pkg-pr-new

pkg-pr-new Bot commented Jul 2, 2026

Copy link
Copy Markdown

Open in StackBlitz

@executor-js/cli

npm i https://pkg.pr.new/@executor-js/cli@1264

@executor-js/config

npm i https://pkg.pr.new/@executor-js/config@1264

@executor-js/execution

npm i https://pkg.pr.new/@executor-js/execution@1264

@executor-js/sdk

npm i https://pkg.pr.new/@executor-js/sdk@1264

@executor-js/codemode-core

npm i https://pkg.pr.new/@executor-js/codemode-core@1264

@executor-js/runtime-quickjs

npm i https://pkg.pr.new/@executor-js/runtime-quickjs@1264

@executor-js/plugin-file-secrets

npm i https://pkg.pr.new/@executor-js/plugin-file-secrets@1264

@executor-js/plugin-graphql

npm i https://pkg.pr.new/@executor-js/plugin-graphql@1264

@executor-js/plugin-keychain

npm i https://pkg.pr.new/@executor-js/plugin-keychain@1264

@executor-js/plugin-mcp

npm i https://pkg.pr.new/@executor-js/plugin-mcp@1264

@executor-js/plugin-onepassword

npm i https://pkg.pr.new/@executor-js/plugin-onepassword@1264

@executor-js/plugin-openapi

npm i https://pkg.pr.new/@executor-js/plugin-openapi@1264

executor

npm i https://pkg.pr.new/executor@1264

commit: f867dbe

@RhysSullivan RhysSullivan force-pushed the ux/openapi-add-visible-submit branch from b8c1523 to 36e5c0b Compare July 2, 2026 17:52
@RhysSullivan RhysSullivan force-pushed the ux/integration-detail-unlock-cta branch 3 times, most recently from f867dbe to 62d477a Compare July 2, 2026 18:20
@RhysSullivan RhysSullivan force-pushed the ux/openapi-add-visible-submit branch 2 times, most recently from 5b945f5 to f8bf0c4 Compare July 2, 2026 18:21
@RhysSullivan RhysSullivan force-pushed the ux/integration-detail-unlock-cta branch from 62d477a to 9ae67c8 Compare July 2, 2026 18:21
@RhysSullivan RhysSullivan force-pushed the ux/integration-detail-unlock-cta branch from 9ae67c8 to b0037e9 Compare July 2, 2026 18:21
@RhysSullivan RhysSullivan changed the base branch from ux/openapi-add-visible-submit to main July 2, 2026 18:21
@RhysSullivan RhysSullivan merged commit b494be4 into main Jul 2, 2026
18 of 21 checks passed
@RhysSullivan RhysSullivan deleted the ux/integration-detail-unlock-cta branch July 2, 2026 18:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant