diff --git a/apps/web/src/components/chat/global-chat-sheet.tsx b/apps/web/src/components/chat/global-chat-sheet.tsx index 1822cac4f2..7c7995db56 100644 --- a/apps/web/src/components/chat/global-chat-sheet.tsx +++ b/apps/web/src/components/chat/global-chat-sheet.tsx @@ -2,6 +2,7 @@ import { lazy, Suspense, useState } from "react" import { useMountEffect } from "@/hooks/use-mount-effect" import { useMapleOrganizationId } from "@/hooks/use-maple-organization" import { isDialogOpen, isEditableTarget } from "@maple/ui/lib/keyboard" +import { aiChatEnabled } from "@/lib/region" const OPEN_CHAT_EVENT = "maple:open-chat-sheet" @@ -35,6 +36,10 @@ export function openGlobalChat() { * history restores from the durable stream on reopen, same as AlertChatSheet. */ export function GlobalChatSheet() { + return aiChatEnabled ? : null +} + +function GlobalChatSheetInner() { const [open, setOpen] = useState(false) const orgId = useMapleOrganizationId() diff --git a/apps/web/src/components/command-palette/command-palette.tsx b/apps/web/src/components/command-palette/command-palette.tsx index 5fad4fc87f..a92a765558 100644 --- a/apps/web/src/components/command-palette/command-palette.tsx +++ b/apps/web/src/components/command-palette/command-palette.tsx @@ -27,6 +27,7 @@ import { } from "@/components/icons" import { isClerkAuthEnabled } from "@/lib/services/common/auth-mode" import { openGlobalChat } from "@/components/chat/global-chat-sheet" +import { aiChatEnabled } from "@/lib/region" import { paletteNavItems } from "@/components/dashboard/nav-items" import { useDashboardPreferences } from "@/hooks/use-dashboard-preferences" import { useDashboardsRead } from "@/hooks/use-dashboard-store" @@ -197,15 +198,19 @@ function PaletteContent({ const isDark = theme === "dark" const actions: PaletteEntry[] = [ - { - id: "action:ask-maple-ai", - title: "Ask Maple AI", - group: "Actions", - keywords: "chat ai assistant maple ask question", - icon: ChatBubbleSparkleIcon, - run: openGlobalChat, - shortcut: "C", - }, + ...(aiChatEnabled + ? [ + { + id: "action:ask-maple-ai", + title: "Ask Maple AI", + group: "Actions", + keywords: "chat ai assistant maple ask question", + icon: ChatBubbleSparkleIcon, + run: openGlobalChat, + shortcut: "C", + } satisfies PaletteEntry, + ] + : []), { id: "action:toggle-theme", title: isDark ? "Switch to light mode" : "Switch to dark mode", diff --git a/apps/web/src/components/dashboard-builder/widgets/widget-actions-context.tsx b/apps/web/src/components/dashboard-builder/widgets/widget-actions-context.tsx index e88f28fc8a..b333fe49c0 100644 --- a/apps/web/src/components/dashboard-builder/widgets/widget-actions-context.tsx +++ b/apps/web/src/components/dashboard-builder/widgets/widget-actions-context.tsx @@ -9,6 +9,7 @@ import { type WidgetFixContext, } from "@/components/chat/widget-fix-context" import { encodeAlertChartToSearchParam } from "@/lib/alerts/widget-chart-param" +import { aiChatEnabled } from "@/lib/region" import { dataSourceRawSql, isQueryDataSource } from "@maple/widgets/dashboard" import { Result, useAtomValue } from "@/lib/effect-atom" import { dashboardSharesAtom } from "@/components/dashboard-builder/toolbar/dashboard-shares" @@ -147,7 +148,7 @@ export function WidgetActionsProvider({ : undefined const fix = - dashboardId && errorKind === "decode" + aiChatEnabled && dashboardId && errorKind === "decode" ? () => { const ctx: WidgetFixContext = { dashboardId, diff --git a/apps/web/src/components/layout/dashboard-layout.tsx b/apps/web/src/components/layout/dashboard-layout.tsx index a0e404c968..3c8ccc6b21 100644 --- a/apps/web/src/components/layout/dashboard-layout.tsx +++ b/apps/web/src/components/layout/dashboard-layout.tsx @@ -17,6 +17,7 @@ import { Tooltip, TooltipContent, TooltipTrigger } from "@maple/ui/components/ui import { Kbd } from "@maple/ui/components/ui/kbd" import { ChatBubbleSparkleIcon, LayoutLeftIcon, LayoutRightIcon } from "@/components/icons" import { openGlobalChat } from "@/components/chat/global-chat-sheet" +import { aiChatEnabled } from "@/lib/region" import { ConnectButton } from "@/components/header/connect-button" import { OnboardingChecklistButton } from "@/components/header/onboarding-checklist-button" import { QuotaBanner } from "@/components/billing/quota-banner" @@ -112,23 +113,25 @@ function Breadcrumbs({ items, children }: { items: BreadcrumbEntry[]; children?:
- - - } - > - - - - Ask Maple AI C - - + {aiChatEnabled && ( + + + } + > + + + + Ask Maple AI C + + + )} {/* Self-gating: renders only when the sidebar has collapsed to a sheet *and* a diff --git a/apps/web/src/lib/region.ts b/apps/web/src/lib/region.ts index cf89dfeb80..9f7c1577e2 100644 --- a/apps/web/src/lib/region.ts +++ b/apps/web/src/lib/region.ts @@ -22,3 +22,6 @@ export function regionAppUrl(region: MapleRegion): string | undefined { /** Whether this deployment has more than one region, and so whether regions are worth showing. */ export const hasMultipleRegions = Object.keys(regionAppUrls).length > 1 + +/** Maple AI chat is off on the EU instance for now; every chat entry point checks this. */ +export const aiChatEnabled = currentRegion !== "eu" diff --git a/apps/web/src/routes/chat.tsx b/apps/web/src/routes/chat.tsx index a7d26faada..fd4326f9d7 100644 --- a/apps/web/src/routes/chat.tsx +++ b/apps/web/src/routes/chat.tsx @@ -1,6 +1,7 @@ -import { createFileRoute } from "@tanstack/react-router" +import { createFileRoute, redirect } from "@tanstack/react-router" import { Schema } from "effect" import { ChatPage } from "@/components/chat/chat-page" +import { aiChatEnabled } from "@/lib/region" import { decodeAlertContextFromSearchParam } from "@/components/chat/alert-context" import { alertContextToInvestigation, @@ -29,6 +30,9 @@ const ChatSearch = Schema.Struct({ export const Route = createFileRoute("/chat")({ component: ChatRoute, validateSearch: Schema.toStandardSchemaV1(ChatSearch), + beforeLoad: () => { + if (!aiChatEnabled) throw redirect({ to: "/" }) + }, }) function ChatRoute() {