From 3769ffa41fe033549ef7027e5285116ecde5abbb Mon Sep 17 00:00:00 2001 From: MaheshtheDev <38828053+MaheshtheDev@users.noreply.github.com> Date: Wed, 24 Jun 2026 01:16:16 +0000 Subject: [PATCH] feat(web): Company Brain connections disconnect and Slack reconnect (#1157) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary - Add disconnect actions for org and personal GitHub/Linear connections on the Company Brain settings page - Show connected Slack workspace name and an admin-only **Reconnect Slack** button (pairs with API admin gate in supermemoryai/mono#1912) - Fix infinite loading skeleton when `/brain/connections` fails by falling back to empty state with a toast ## Test plan - [ ] Open Settings → Company Brain connections as org admin - [ ] Confirm Slack team name shows when workspace is connected - [ ] Confirm **Reconnect Slack** is visible for admin/owner only - [ ] Connect and disconnect GitHub/Linear for org (admin) and personal scopes - [ ] Simulate failed connections fetch (e.g. offline) and confirm page renders instead of infinite skeleton --- .../settings/company-brain-connections.tsx | 152 +++++++++++++++++- 1 file changed, 144 insertions(+), 8 deletions(-) diff --git a/apps/web/components/settings/company-brain-connections.tsx b/apps/web/components/settings/company-brain-connections.tsx index b9045e8b..7720969e 100644 --- a/apps/web/components/settings/company-brain-connections.tsx +++ b/apps/web/components/settings/company-brain-connections.tsx @@ -3,7 +3,7 @@ import { authClient } from "@lib/auth" import { cn } from "@lib/utils" import { useQuery } from "@tanstack/react-query" -import { Check, Loader2, Lock } from "lucide-react" +import { Loader2, Lock } from "lucide-react" import { useCallback, useEffect, useState } from "react" import { toast } from "sonner" import { dmSans125ClassName } from "@/lib/fonts" @@ -14,6 +14,67 @@ const BACKEND = process.env.NEXT_PUBLIC_BACKEND_URL ?? "https://api.supermemory.ai" type ConnRow = { toolkit: string; org: boolean; user: boolean } +type SlackStatus = { connected: boolean; teamName: string | null } + +function SecondaryButton({ + children, + href, +}: { + children: React.ReactNode + href: string +}) { + return ( + + {children} + + ) +} + +function SlackMark({ className }: { className?: string }) { + return ( + + ) +} function GithubMark({ className }: { className?: string }) { return ( @@ -73,16 +134,20 @@ function AppCard({ toolkit, connected, canConnect, + canDisconnect, lockedHint, busy, onConnect, + onDisconnect, }: { toolkit: string connected: boolean canConnect: boolean + canDisconnect: boolean lockedHint?: string busy: boolean onConnect: () => void + onDisconnect: () => void }) { const meta = TOOLKITS[toolkit] ?? { label: toolkit, @@ -116,7 +181,13 @@ function AppCard({
+
+ Slack · {slackStatus.teamName} +
+ ) : null} + {isAdmin ? ( +