Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 2 additions & 93 deletions apps/design-system/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import '@/styles/globals.css'

import type { Metadata, Viewport } from 'next'

import { genFaviconData } from 'common/MetaFavicons/app-router'

import { Providers } from './Providers'
import { Toaster } from './toaster'
import { inter, manrope, sourceCodePro } from '@/lib/fonts'
Expand All @@ -11,99 +13,6 @@ const className = `${inter.variable} ${manrope.variable} ${sourceCodePro.variabl

const BASE_PATH = process.env.NEXT_PUBLIC_BASE_PATH || '/design-system'

const genFaviconData = (basePath: string): Metadata['icons'] => ({
icon: {
url: `${basePath}/favicon/favicon.ico`,
type: 'image/x-icon',
},
shortcut: `${basePath}/favicon/favicon.ico`,
apple: `${basePath}/favicon/favicon.ico`,
other: [
{
rel: 'apple-touch-icon-precomposed',
url: `${basePath}/favicon/apple-icon-57x57.png`,
sizes: '57x57',
},
{
rel: 'apple-touch-icon-precomposed',
url: `${basePath}/favicon/apple-icon-60x60.png`,
sizes: '60x60',
},
{
rel: 'apple-touch-icon-precomposed',
url: `${basePath}/favicon/apple-icon-72x72.png`,
sizes: '72x72',
},
{
rel: 'apple-touch-icon-precomposed',
url: `${basePath}/favicon/apple-icon-76x76.png`,
sizes: '76x76',
},
{
rel: 'apple-touch-icon-precomposed',
url: `${basePath}/favicon/apple-icon-114x114.png`,
sizes: '114x114',
},
{
rel: 'apple-touch-icon-precomposed',
url: `${basePath}/favicon/apple-icon-120x120.png`,
sizes: '120x120',
},
{
rel: 'apple-touch-icon-precomposed',
url: `${basePath}/favicon/apple-icon-144x144.png`,
sizes: '144x144',
},
{
rel: 'apple-touch-icon-precomposed',
url: `${basePath}/favicon/apple-icon-152x152.png`,
sizes: '152x152',
},
{
rel: 'icon',
url: `${basePath}/favicon/favicon-16x16.png`,
type: 'image/png',
sizes: '16x16',
},
{
rel: 'icon',
url: `${basePath}/favicon/favicon-32x32.png`,
type: 'image/png',
sizes: '32x32',
},
{
rel: 'icon',
url: `${basePath}/favicon/favicon-48x48.png`,
type: 'image/png',
sizes: '48x48',
},
{
rel: 'icon',
url: `${basePath}/favicon/favicon-96x96.png`,
type: 'image/png',
sizes: '96x96',
},
{
rel: 'icon',
url: `${basePath}/favicon/favicon-128x128.png`,
type: 'image/png',
sizes: '128x128',
},
{
rel: 'icon',
url: `${basePath}/favicon/favicon-180x180.png`,
type: 'image/png',
sizes: '180x180',
},
{
rel: 'icon',
url: `${basePath}/favicon/favicon-196x196.png`,
type: 'image/png',
sizes: '196x196',
},
],
})

export const metadata: Metadata = {
applicationName: 'Supabase Design System',
title: 'Supabase Design System',
Expand Down
2 changes: 1 addition & 1 deletion apps/docs/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ const additionalResources = [
title: 'AI tools',
description: 'Develop with Supabase AI-first using plugins, MCP, and skills.',
icon: 'ai-tools',
href: '/guides/ai',
href: '/guides/ai-tools',
},
{
title: 'Platform guides',
Expand Down
2 changes: 1 addition & 1 deletion apps/docs/content/_partials/project_setup.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Now set up the database schema. You can use the "User Management Starter" quicks
<TabPanel id="dashboard" label="Dashboard">

1. Go to the [SQL Editor](/dashboard/project/_/sql) page in the Dashboard.
2. Click **User Management Starter** under the **Community > Quickstarts** tab.
2. Click **User Management Starter** under the **Reference > Examples** tab.
3. Click **Run**.

<Admonition type="note">
Expand Down
2 changes: 1 addition & 1 deletion apps/docs/content/guides/ai-tools/ai-prompts.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ You can load these prompts into various tools. Here are common options and where
| JetBrains IDEs | `guidelines.md` | [Customize guidelines](https://www.jetbrains.com/help/junie/customize-guidelines.html) |
| Gemini CLI | `GEMINI.md` | [Gemini CLI codelab](https://codelabs.developers.google.com/gemini-cli-hands-on) |
| VS Code | `.instructions.md` | Configure `.instructions.md` |
| Windsurf | `guidelines.md` | Configure `guidelines.md` |
| Devin Desktop | `guidelines.md` | Configure `guidelines.md` |
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const { data, error } = await supabase
.not('id', 'in', '(5,6,7,8,9,...10,000)')
```

To circumvent this issue, you must use [RPCs](/docs/reference/javascript/explain?queryGroups=example&example=call-a-postgres-function-with-arguments). They are database functions that you can call from the API. Instead of including a query's structure within the URL or header, they move it into the request's payload.
To circumvent this issue, you must use [RPCs](/docs/reference/javascript/rpc?queryGroups=example&example=call-a-postgres-function-with-arguments). They are database functions that you can call from the API. Instead of including a query's structure within the URL or header, they move it into the request's payload.

Here is a basic example of a [database function](/docs/guides/database/functions)

Expand All @@ -50,7 +50,7 @@ end;
$$;
```

The [RPC](/docs/reference/javascript/explain?queryGroups=example&example=call-a-postgres-function-with-arguments) can then call the function with an array that contains more than 16KB of data
The [RPC](/docs/reference/javascript/rpc?queryGroups=example&example=call-a-postgres-function-with-arguments) can then call the function with an array that contains more than 16KB of data

```javascript
const { data, error } = await supabase.rpc('example', { id: ['e2f34fb9-bbf9-4649-9b2f-09ec56e67a42', ...900 more UUIDs] })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ The Postgres EXPLAIN command shows the execution plan of a SQL query. This plan
**Using EXPLAIN with supabase-js Library**

1. Follow the [Performance Debugging Guide](/docs/guides/database/debugging-performance) to enable the functionality on your project.
2. Once debugging is enabled, you can use the [EXPLAIN](/docs/reference/javascript/explain?queryGroups=example&example=get-execution-plan-with-analyze-and-verbose) function in your application code. Here's how to use it
2. Once debugging is enabled, you can use the [EXPLAIN](/docs/reference/javascript/using-modifiers-explain?queryGroups=example&example=get-execution-plan-with-analyze-and-verbose) function in your application code. Here's how to use it

```
const { data, error } = await supabase
Expand Down
2 changes: 1 addition & 1 deletion apps/docs/data/content-listings/ai-tools.data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const ICON_ASSETS: Record<string, { icon: string; hasLightIcon?: boolean }> = {
kimi: { icon: '/docs/img/icons/agent-kimi-icon', hasLightIcon: true },
vscode: { icon: '/docs/img/icons/agent-vscode-icon', hasLightIcon: false },
antigravity: { icon: '/docs/img/icons/agent-antigravity-icon', hasLightIcon: false },
windsurf: { icon: '/docs/img/icons/agent-windsurf-icon', hasLightIcon: true },
windsurf: { icon: '/docs/img/icons/agent-devin-icon', hasLightIcon: true },
goose: { icon: '/docs/img/icons/agent-goose-icon', hasLightIcon: true },
factory: { icon: '/docs/img/icons/agent-factory-icon', hasLightIcon: true },
opencode: { icon: '/docs/img/icons/agent-opencode-icon', hasLightIcon: true },
Expand Down
3 changes: 3 additions & 0 deletions apps/docs/public/img/icons/agent-devin-icon-light.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions apps/docs/public/img/icons/agent-devin-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/studio/TANSTACK_MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,7 @@ These are the layout-only TanStack files. Most hold a single product layout comp

- [x] A `routes/project/$ref/explorer/index.tsx` ← `pages/project/[ref]/explorer/index.tsx`
- [x] A `routes/project/$ref/explorer/notebook/$id.tsx` ← `pages/project/[ref]/explorer/notebook/[id].tsx`
- [x] A `routes/project/$ref/explorer/chat/$id.tsx` ← `pages/project/[ref]/explorer/chat/[id].tsx`

### Auth shell — `/sign-in`, `/sign-up`, etc.

Expand Down
103 changes: 103 additions & 0 deletions apps/studio/components/interfaces/Explorer/ChatEditor.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import { useParams } from 'common'
import { Loader2, MessageSquare } from 'lucide-react'
import { useRouter } from 'next/router'
import { useEffect, useEffectEvent } from 'react'
import { Button } from 'ui'

import { ExplorerChatToolbar } from './ExplorerChatToolbar'
import { useCreateChat } from './hooks'
import { SIDEBAR_KEYS } from '@/components/layouts/ProjectLayout/LayoutSidebar/LayoutSidebarProvider'
import { AssistantChat } from '@/components/ui/AIAssistantPanel/AssistantChat'
import { useAiAssistantState, useAiAssistantStateSnapshot } from '@/state/ai-assistant-state'
import { useSidebarManagerSnapshot } from '@/state/sidebar-manager-state'
import { createTabId, useTabsStateSnapshot } from '@/state/tabs'

export const ChatEditor = () => {
const { id, ref } = useParams()
const router = useRouter()
const tabs = useTabsStateSnapshot()
const aiAssistant = useAiAssistantStateSnapshot()
const aiAssistantState = useAiAssistantState()
const { createChat, openChat } = useCreateChat()
const { activeSidebar } = useSidebarManagerSnapshot()
const chat = id ? aiAssistant.chats[id] : undefined
const chatInstance = id ? aiAssistant.chatInstances[id] : undefined
const tabId = id ? createTabId('chat', { id }) : undefined
const shortcutsEnabled = activeSidebar?.id !== SIDEBAR_KEYS.AI_ASSISTANT

const syncChatTab = useEffectEvent(() => {
if (!id || !chat) return

aiAssistantState.ensureChatInstance(id)
const nextTabId = createTabId('chat', { id })
tabs.addTab({
id: nextTabId,
type: 'chat',
label: chat.name,
metadata: { chatId: id },
isPreview: false,
})
tabs.updateTab(nextTabId, { label: chat.name })
})

const removeDeletedChatTab = useEffectEvent(() => {
if (!tabId || !tabs.openTabs.includes(tabId)) return

tabs.handleTabClose({
id: tabId,
router,
editor: 'explorer',
onClearDashboardHistory: () => {},
})
})

useEffect(() => syncChatTab(), [id, chat?.name])

useEffect(() => {
if (aiAssistant.isInitialized && id && !chat) removeDeletedChatTab()
}, [aiAssistant.isInitialized, id, chat])

if (!aiAssistant.isInitialized || (chat && !chatInstance)) {
return (
<div className="h-full bg-surface-100 flex items-center justify-center">
<Loader2 className="animate-spin text-foreground-muted" />
</div>
)
}

if (!id || !chat) {
return (
<div className="h-full bg-surface-100 flex flex-col items-center justify-center gap-3 px-6 text-center">
<MessageSquare className="text-foreground-muted" />
<div>
<h2 className="text-sm text-foreground">Chat not found</h2>
<p className="text-sm text-foreground-lighter">
This chat may have been deleted or is no longer available.
</p>
</div>
<Button variant="default" onClick={() => router.push(`/project/${ref}/explorer`)}>
Back to Explorer
</Button>
</div>
)
}

const handleBranchChat = (messageId: string) => {
const branchId = aiAssistantState.createBranch(id, messageId)
if (branchId) openChat(branchId)
}

return (
<AssistantChat
chatId={id}
shortcutsEnabled={shortcutsEnabled}
className="bg-surface-100"
onNewChat={() => createChat()}
onSelectChat={openChat}
onBranchChat={handleBranchChat}
renderHeader={(headerProps) => (
<ExplorerChatToolbar {...headerProps} chatId={id} shortcutsEnabled={shortcutsEnabled} />
)}
/>
)
}
Loading
Loading