IndexAdvisorDisabledState.tsx97 lines · main
1import { useParams } from 'common'
2import Link from 'next/link'
3import { toast } from 'sonner'
4import { Alert, AlertDescription, AlertTitle, Button } from 'ui'
5
6import { Markdown } from '../../Markdown'
7import { getIndexAdvisorExtensions } from './index-advisor.utils'
8import { DocsButton } from '@/components/ui/DocsButton'
9import { useDatabaseExtensionEnableMutation } from '@/data/database-extensions/database-extension-enable-mutation'
10import { useDatabaseExtensionsQuery } from '@/data/database-extensions/database-extensions-query'
11import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
12import { DOCS_URL } from '@/lib/constants'
13
14export const IndexAdvisorDisabledState = () => {
15 const { ref } = useParams()
16 const { data: project } = useSelectedProjectQuery()
17 const { data: extensions } = useDatabaseExtensionsQuery({
18 projectRef: project?.ref,
19 connectionString: project?.connectionString,
20 })
21 const { hypopg, indexAdvisor } = getIndexAdvisorExtensions(extensions)
22
23 const { mutateAsync: enableExtension, isPending: isEnablingExtension } =
24 useDatabaseExtensionEnableMutation()
25
26 const onEnableIndexAdvisor = async () => {
27 if (project === undefined) return console.error('Project is required')
28
29 try {
30 if (hypopg?.installed_version === null) {
31 await enableExtension({
32 projectRef: project?.ref,
33 connectionString: project?.connectionString,
34 name: hypopg.name,
35 schema: hypopg?.schema ?? 'extensions',
36 version: hypopg.default_version,
37 })
38 }
39 if (indexAdvisor?.installed_version === null) {
40 await enableExtension({
41 projectRef: project?.ref,
42 connectionString: project?.connectionString,
43 name: indexAdvisor.name,
44 schema: indexAdvisor?.schema ?? 'extensions',
45 version: indexAdvisor.default_version,
46 })
47 }
48 toast.success('Successfully enabled index advisor!')
49 } catch (error: any) {
50 toast.error(`Failed to enable index advisor: ${error.message}`)
51 }
52 }
53
54 return (
55 <Alert className="mb-6">
56 <AlertTitle>
57 <Markdown
58 className="text-foreground"
59 content={
60 indexAdvisor === undefined
61 ? 'Newer version of Postgres required'
62 : 'Postgres extensions `index_advisor` and `hypopg` required'
63 }
64 />
65 </AlertTitle>
66 <AlertDescription>
67 <Markdown
68 content={
69 indexAdvisor === undefined
70 ? 'Upgrade to the latest version of Postgres to get recommendations on indexes for your queries'
71 : 'These extensions can help in recommending database indexes to reduce the costs of your query.'
72 }
73 />
74 </AlertDescription>
75
76 <AlertDescription className="mt-3">
77 <div className="flex items-center gap-x-2">
78 {indexAdvisor === undefined ? (
79 <Button asChild type="default">
80 <Link href={`/project/${ref}/settings/infrastructure`}>Upgrade Postgres version</Link>
81 </Button>
82 ) : (
83 <Button
84 type="default"
85 disabled={isEnablingExtension}
86 loading={isEnablingExtension}
87 onClick={() => onEnableIndexAdvisor()}
88 >
89 Enable extensions
90 </Button>
91 )}
92 <DocsButton href={`${DOCS_URL}/guides/database/extensions/index_advisor`} />
93 </div>
94 </AlertDescription>
95 </Alert>
96 )
97}