more ai spots

This commit is contained in:
Saxon Fletcher committed 2025-10-23 15:05:19 +10:00
1 parent 2e4f484937
commit 94fcb91567
8 files changed
+27 -44

No files matched your search

@@ -19,13 +19,15 @@ import {
DropdownMenuItem,
DropdownMenuTrigger,
} from 'ui'
import { SIDEBAR_KEYS } from 'components/layouts/ProjectLayout/LayoutSidebar/LayoutSidebarProvider'
import { useSidebarManagerSnapshot } from 'state/sidebar-manager-state'
export const DeployEdgeFunctionButton = () => {
const router = useRouter()
const { ref } = useParams()
const { data: org } = useSelectedOrganizationQuery()
const snap = useAiAssistantStateSnapshot()
const { openSidebar } = useSidebarManagerSnapshot()
const { mutate: sendEvent } = useSendEventMutation()
return (
@@ -85,9 +87,9 @@ export const DeployEdgeFunctionButton = () => {
<DropdownMenuItem
className="gap-4"
onSelect={() => {
openSidebar(SIDEBAR_KEYS.AI_ASSISTANT)
snap.newChat({
name: 'Create new edge function',
open: true,
initialInput: `Create a new edge function that ...`,
suggestions: {
title:
@@ -27,6 +27,8 @@ import {
TabsTrigger_Shadcn_ as TabsTrigger,
} from 'ui'
import ShimmeringLoader from 'ui-patterns/ShimmeringLoader'
import { SIDEBAR_KEYS } from 'components/layouts/ProjectLayout/LayoutSidebar/LayoutSidebarProvider'
import { useSidebarManagerSnapshot } from 'state/sidebar-manager-state'
interface SlowQuery {
rolname: string
@@ -45,6 +47,7 @@ export const AdvisorWidget = () => {
}
)
const snap = useAiAssistantStateSnapshot()
const { openSidebar } = useSidebarManagerSnapshot()
const securityLints = useMemo(
() => (lints ?? []).filter((lint: Lint) => lint.categories.includes('SECURITY')),
@@ -147,9 +150,9 @@ export const AdvisorWidget = () => {
onClick={(e) => {
e.stopPropagation()
e.preventDefault()
openSidebar(SIDEBAR_KEYS.AI_ASSISTANT)
snap.newChat({
name: 'Summarize lint',
open: true,
initialInput: `Summarize the issue and suggest fixes for the following lint item:
Title: ${lintInfoMap.find((item) => item.name === lint.name)?.title ?? lint.title}
Entity: ${(lint.metadata && (lint.metadata.entity || (lint.metadata.schema && lint.metadata.name && `${lint.metadata.schema}.${lint.metadata.name}`))) ?? 'N/A'}
@@ -141,7 +141,6 @@ export const AdvisorSection = () => {
e.preventDefault()
snap.newChat({
name: 'Summarize lint',
open: true,
initialInput: createLintSummaryPrompt(lint),
})
if (projectRef && organization?.slug) {
@@ -8,6 +8,8 @@ import { ExternalLink } from 'lucide-react'
import { useAiAssistantStateSnapshot } from 'state/ai-assistant-state'
import { AiIconAnimation, Button } from 'ui'
import { EntityTypeIcon, LintCTA, LintEntity } from './Linter.utils'
import { SIDEBAR_KEYS } from 'components/layouts/ProjectLayout/LayoutSidebar/LayoutSidebarProvider'
import { useSidebarManagerSnapshot } from 'state/sidebar-manager-state'
interface LintDetailProps {
lint: Lint
@@ -17,6 +19,7 @@ interface LintDetailProps {
const LintDetail = ({ lint, projectRef, onAskAssistant }: LintDetailProps) => {
const snap = useAiAssistantStateSnapshot()
const { openSidebar } = useSidebarManagerSnapshot()
return (
<div>
@@ -41,9 +44,9 @@ const LintDetail = ({ lint, projectRef, onAskAssistant }: LintDetailProps) => {
icon={<AiIconAnimation className="scale-75 w-3 h-3" />}
onClick={() => {
onAskAssistant?.()
openSidebar(SIDEBAR_KEYS.AI_ASSISTANT)
snap.newChat({
name: 'Summarize lint',
open: true,
initialInput: createLintSummaryPrompt(lint),
})
}}
@@ -20,12 +20,15 @@ import {
PopoverTrigger_Shadcn_,
Popover_Shadcn_,
} from 'ui'
import { SIDEBAR_KEYS } from '../LayoutSidebar/LayoutSidebarProvider'
import { useSidebarManagerSnapshot } from 'state/sidebar-manager-state'
export const HelpPopover = () => {
const router = useRouter()
const { data: project } = useSelectedProjectQuery()
const { data: org } = useSelectedOrganizationQuery()
const snap = useAiAssistantStateSnapshot()
const { openSidebar } = useSidebarManagerSnapshot()
const { mutate: sendEvent } = useSendEventMutation()
@@ -69,9 +72,9 @@ export const HelpPopover = () => {
size="tiny"
icon={<AiIconAnimation allowHoverEffect size={14} />}
onClick={() => {
openSidebar(SIDEBAR_KEYS.AI_ASSISTANT)
snap.newChat({
name: 'Support',
open: true,
initialInput: `I need help with my project`,
suggestions: {
title:
@@ -3,14 +3,8 @@ import { act, fireEvent, render, waitFor } from '@testing-library/react'
import { ReactNode } from 'react'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import {
getSidebarManagerSnapshot,
sidebarManagerState,
} from 'state/sidebar-manager-state'
import {
LayoutSidebarProvider,
SIDEBAR_KEYS,
} from './LayoutSidebarProvider'
import { getSidebarManagerSnapshot, sidebarManagerState } from 'state/sidebar-manager-state'
import { LayoutSidebarProvider, SIDEBAR_KEYS } from './LayoutSidebarProvider'
vi.mock('components/ui/AIAssistantPanel/AIAssistant', () => ({
AIAssistant: () => <div data-testid="ai-assistant-sidebar" />,
@@ -1,28 +1,17 @@
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { act, render, screen, waitFor } from '@testing-library/react'
import Router from 'next/router'
import router from 'next-router-mock'
import { ReactNode } from 'react'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import {
LayoutSidebarProvider,
SIDEBAR_KEYS,
} from './LayoutSidebarProvider'
import { LayoutSidebar } from './index'
import { LayoutSidebarProvider, SIDEBAR_KEYS } from './LayoutSidebarProvider'
import { sidebarManagerState } from 'state/sidebar-manager-state'
vi.mock('components/ui/AIAssistantPanel/AIAssistant', () => ({
AIAssistant: () => <div data-testid="ai-assistant-sidebar">AI Assistant</div>,
}))
vi.mock('next/router', async () => {
const actual = await vi.importActual<typeof import('next/router')>('next/router')
return {
...actual,
useRouter: () => Router,
}
})
const resetSidebarManagerState = () => {
Object.keys(sidebarManagerState.sidebars).forEach((id) => {
sidebarManagerState.unregisterSidebar(id)
@@ -40,21 +29,7 @@ describe('LayoutSidebar', () => {
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
)
Object.assign(Router, {
isReady: true,
query: {},
events: { on: vi.fn(), off: vi.fn(), emit: vi.fn() },
push: vi.fn(),
replace: vi.fn(),
prefetch: vi.fn(),
pathname: '/',
route: '/',
asPath: '/',
basePath: '',
back: vi.fn(),
beforePopState: vi.fn(),
reload: vi.fn(),
})
router.setCurrentUrl('/')
})
afterEach(() => {
@@ -62,6 +37,7 @@ describe('LayoutSidebar', () => {
queryClient.clear()
localStorage.clear()
vi.clearAllMocks()
router.setCurrentUrl('/')
})
const renderSidebar = () =>
@@ -93,7 +69,7 @@ describe('LayoutSidebar', () => {
})
it('auto-opens when sidebar query param matches a registered sidebar', async () => {
Object.assign(Router, { isReady: true, query: { sidebar: SIDEBAR_KEYS.AI_ASSISTANT } })
router.setCurrentUrl(`/?sidebar=${SIDEBAR_KEYS.AI_ASSISTANT}`)
renderSidebar()
@@ -42,6 +42,8 @@ import {
TooltipContent,
TooltipTrigger,
} from 'ui'
import { SIDEBAR_KEYS } from 'components/layouts/ProjectLayout/LayoutSidebar/LayoutSidebarProvider'
import { useSidebarManagerSnapshot } from 'state/sidebar-manager-state'
// Array of adjectives and nouns for random function name generation
const ADJECTIVES = [
@@ -104,6 +106,7 @@ const NewFunctionPage = () => {
const snap = useAiAssistantStateSnapshot()
const { mutate: sendEvent } = useSendEventMutation()
const showStripeExample = useIsFeatureEnabled('edge_functions:show_stripe_example')
const { openSidebar } = useSidebarManagerSnapshot()
const [files, setFiles] = useState<
{ id: number; name: string; content: string; selected?: boolean }[]
@@ -167,9 +170,9 @@ const NewFunctionPage = () => {
const handleChat = () => {
const selectedFile = files.find((f) => f.selected) ?? files[0]
openSidebar(SIDEBAR_KEYS.AI_ASSISTANT)
snap.newChat({
name: 'Explain edge function',
open: true,
sqlSnippets: [selectedFile.content],
initialInput: 'Help me understand and improve this edge function...',
suggestions: {