From d287421fadf126076a128edd717081e33b53b38c Mon Sep 17 00:00:00 2001 From: Michael Matloka Date: Wed, 15 Apr 2026 02:17:08 +0200 Subject: [PATCH] feat: Gate Inbox behind GitHub integration and improve GH connection UX - Show Welcome pane instead of "warming up" when no GitHub integration exists - Add GitHub connection card to signal sources config modal - Disable signal source toggles until GitHub is connected - Fix redirect URL after GitHub OAuth (was 404ing with double-concatenated URL) - Make onboarding Connect GitHub button retryable during auth flow - Show GitHub profile pictures for suggested reviewers - Add github_login to available_reviewers API response --- apps/code/src/renderer/api/posthogClient.ts | 1 + .../inbox/components/InboxSignalsTab.tsx | 7 +- .../inbox/components/InboxSourcesDialog.tsx | 12 +- .../list/GitHubConnectionBanner.tsx | 3 +- .../list/SuggestedReviewerFilterMenu.tsx | 37 +++-- .../utils/suggestedReviewerFilters.test.ts | 1 + .../inbox/utils/suggestedReviewerFilters.ts | 3 + .../components/GitIntegrationStep.tsx | 13 +- .../sections/GitHubIntegrationSection.tsx | 147 ++++++++++++++++++ .../sections/SignalSourcesSettings.tsx | 70 ++++++--- apps/code/src/renderer/styles/globals.css | 6 + apps/code/src/shared/types.ts | 1 + 12 files changed, 254 insertions(+), 47 deletions(-) create mode 100644 apps/code/src/renderer/features/settings/components/sections/GitHubIntegrationSection.tsx diff --git a/apps/code/src/renderer/api/posthogClient.ts b/apps/code/src/renderer/api/posthogClient.ts index 2093a5dc8..ffbf2ecc7 100644 --- a/apps/code/src/renderer/api/posthogClient.ts +++ b/apps/code/src/renderer/api/posthogClient.ts @@ -305,6 +305,7 @@ function normalizeAvailableSuggestedReviewer( uuid: normalizedUuid, name: optionalString(value.name) ?? "", email: optionalString(value.email) ?? "", + github_login: optionalString(value.github_login) ?? "", }; } diff --git a/apps/code/src/renderer/features/inbox/components/InboxSignalsTab.tsx b/apps/code/src/renderer/features/inbox/components/InboxSignalsTab.tsx index 74515f2c5..40651bb41 100644 --- a/apps/code/src/renderer/features/inbox/components/InboxSignalsTab.tsx +++ b/apps/code/src/renderer/features/inbox/components/InboxSignalsTab.tsx @@ -22,6 +22,7 @@ import { filterReportsBySearch, } from "@features/inbox/utils/filterReports"; import { INBOX_REFETCH_INTERVAL_MS } from "@features/inbox/utils/inboxConstants"; +import { useRepositoryIntegration } from "@hooks/useIntegrations"; import { Box, Flex, ScrollArea } from "@radix-ui/themes"; import type { SignalReportsQueryParams } from "@shared/types"; import { useNavigationStore } from "@stores/navigationStore"; @@ -48,6 +49,9 @@ export function InboxSignalsTab() { (s) => s.suggestedReviewerFilter, ); + // ── GitHub integration ─────────────────────────────────────────────── + const { hasGithubIntegration } = useRepositoryIntegration(); + // ── Signal source configs ─────────────────────────────────────────────── const { data: signalSourceConfigs } = useSignalSourceConfigs(); const hasSignalSources = signalSourceConfigs?.some((c) => c.enabled) ?? false; @@ -576,7 +580,7 @@ export function InboxSignalsTab() { }} > - {!hasSignalSources ? ( + {!hasSignalSources || !hasGithubIntegration ? ( setSourcesDialogOpen(true)} /> ) : ( ); diff --git a/apps/code/src/renderer/features/inbox/components/InboxSourcesDialog.tsx b/apps/code/src/renderer/features/inbox/components/InboxSourcesDialog.tsx index 1c58cd1cf..f13f47424 100644 --- a/apps/code/src/renderer/features/inbox/components/InboxSourcesDialog.tsx +++ b/apps/code/src/renderer/features/inbox/components/InboxSourcesDialog.tsx @@ -6,12 +6,14 @@ interface InboxSourcesDialogProps { open: boolean; onOpenChange: (open: boolean) => void; hasSignalSources: boolean; + hasGithubIntegration: boolean; } export function InboxSourcesDialog({ open, onOpenChange, hasSignalSources, + hasGithubIntegration, }: InboxSourcesDialogProps) { return ( @@ -32,12 +34,18 @@ export function InboxSourcesDialog({ - {hasSignalSources ? ( + {hasSignalSources && hasGithubIntegration ? ( ) : ( - + diff --git a/apps/code/src/renderer/features/inbox/components/list/GitHubConnectionBanner.tsx b/apps/code/src/renderer/features/inbox/components/list/GitHubConnectionBanner.tsx index 698426284..c477618c7 100644 --- a/apps/code/src/renderer/features/inbox/components/list/GitHubConnectionBanner.tsx +++ b/apps/code/src/renderer/features/inbox/components/list/GitHubConnectionBanner.tsx @@ -69,8 +69,7 @@ export function GitHubConnectionBanner() { PostHog Code suggests report ownership using cutting-edge{" "} git blame technology.
- For this, connect your GitHub profile (different from connecting - repositories). + For relevant reports, connect your GitHub profile. } diff --git a/apps/code/src/renderer/features/inbox/components/list/SuggestedReviewerFilterMenu.tsx b/apps/code/src/renderer/features/inbox/components/list/SuggestedReviewerFilterMenu.tsx index fc2b4e3f6..6d3cc4320 100644 --- a/apps/code/src/renderer/features/inbox/components/list/SuggestedReviewerFilterMenu.tsx +++ b/apps/code/src/renderer/features/inbox/components/list/SuggestedReviewerFilterMenu.tsx @@ -146,19 +146,32 @@ export function SuggestedReviewerFilterMenu() { className="flex w-full items-start justify-between rounded-sm px-1 py-1 text-left text-[13px] text-gray-12 transition-colors hover:bg-gray-3 focus-visible:bg-gray-3 focus-visible:outline-none" onClick={() => toggleSuggestedReviewer(reviewer.uuid)} > - - - {displayName} - - {reviewer.email ? ( - - {reviewer.email} - + + {reviewer.github_login ? ( + + e.currentTarget.classList.add("loaded") + } + /> ) : null} + + + {displayName} + + {reviewer.email ? ( + + {reviewer.email} + + ) : null} + { if (!cloudRegion || !selectedProjectId || !client) return; + stopPolling(); setConnectingGithub(true); try { await trpcClient.githubIntegration.startFlow.mutate({ @@ -365,12 +366,8 @@ export function GitIntegrationStep({ alignItems: "center", }} > - - Opens GitHub to authorize the PostHog app + {isConnecting + ? "Waiting for authorization\u2026 Click again if the browser tab was closed." + : "Opens GitHub to authorize the PostHog app"} + + ) : ( + + )} +
+ ); +} diff --git a/apps/code/src/renderer/features/settings/components/sections/SignalSourcesSettings.tsx b/apps/code/src/renderer/features/settings/components/sections/SignalSourcesSettings.tsx index 53fe39ce9..0618d1cec 100644 --- a/apps/code/src/renderer/features/settings/components/sections/SignalSourcesSettings.tsx +++ b/apps/code/src/renderer/features/settings/components/sections/SignalSourcesSettings.tsx @@ -1,8 +1,10 @@ import { DataSourceSetup } from "@features/inbox/components/DataSourceSetup"; import { SignalSourceToggles } from "@features/inbox/components/SignalSourceToggles"; import { useSignalSourceManager } from "@features/inbox/hooks/useSignalSourceManager"; +import { GitHubIntegrationSection } from "@features/settings/components/sections/GitHubIntegrationSection"; +import { useRepositoryIntegration } from "@hooks/useIntegrations"; import { useMeQuery } from "@hooks/useMeQuery"; -import { Flex, Text } from "@radix-ui/themes"; +import { Box, Flex, Text, Tooltip } from "@radix-ui/themes"; export function SignalSourcesSettings() { const { @@ -22,6 +24,8 @@ export function SignalSourcesSettings() { const { data: me } = useMeQuery(); const isStaff = me?.is_staff ?? false; + const { hasGithubIntegration } = useRepositoryIntegration(); + if (isLoading) { return ( @@ -37,28 +41,48 @@ export function SignalSourcesSettings() { Choose which sources to enable for this project. - {setupSource ? ( - void handleSetupComplete()} - onCancel={handleSetupCancel} - /> - ) : ( - void handleToggle(source, enabled)} - sourceStates={sourceStates} - sessionAnalysisStatus={sessionAnalysisStatus} - onSetup={handleSetup} - evaluations={isStaff ? evaluations : undefined} - evaluationsUrl={isStaff ? evaluationsUrl : undefined} - onToggleEvaluation={ - isStaff - ? (id, enabled) => void handleToggleEvaluation(id, enabled) - : undefined - } - /> - )} + + + ); } diff --git a/apps/code/src/renderer/styles/globals.css b/apps/code/src/renderer/styles/globals.css index 8193f1328..d85cfe9eb 100644 --- a/apps/code/src/renderer/styles/globals.css +++ b/apps/code/src/renderer/styles/globals.css @@ -897,6 +897,12 @@ button, transition: none; } +/* GitHub avatar loading placeholder */ +.github-avatar:not(.loaded) { + outline: 1px dashed var(--gray-7); + outline-offset: -1px; +} + /* Inbox warming-up ellipsis wave */ @keyframes inboxEllipsisWave { 0%, diff --git a/apps/code/src/shared/types.ts b/apps/code/src/shared/types.ts index ef98e20e9..8946822bb 100644 --- a/apps/code/src/shared/types.ts +++ b/apps/code/src/shared/types.ts @@ -343,6 +343,7 @@ export interface AvailableSuggestedReviewer { uuid: string; name: string; email: string; + github_login: string; } export interface SuggestedReviewer {