Files
supabase/apps/studio/components/interfaces/Integrations/Integration/IntegrationOverviewTab.tsx
Ivan Vasilov c5bf65b0b4 feat: Create FDW for S3 Vectors buckets (#40206)
* Fix childProps in Admonition so that they're added as a prop to the main div.

* Replace the admonition with Alert in Wrapper tab page to add a gap between childs.

* Add s3 vectors fdw.

* Minor fix to FormSection.

* Update the fdw mutations to support passing in options.

* Refactor the vector flow to create fdws.

* Revert cron description change.

* If the bucket can't be created, don't create a fdw.

* Update/delete the fdw when deleting a table or a bucket.

* Minor fixes.

* Clean up the delete modal.

* Handle edge cases when missing a wrapper.

* Remove the admonition in the create bucket modal.

* Fix the loading state when creating a bucket.

* Fix the createWrapper sheet to work with s3 vectors.

* Fix undefined wrapperMeta issue.

* Create the schema when installing a wrapper.

* Tiny cleanup.

* Clean up unneeded useState. Create a wrapper only if the all conditions are met.

* Fix all comments.

* Add s3 vectors for docs.

* Add a link and fix the file name for S3 Vectors in docs.

* Hide the table editor button if the wrapper instance is missing.

* Small fixes.
2025-11-12 11:00:38 +01:00

91 lines
3.7 KiB
TypeScript

import { useRouter } from 'next/router'
import { PropsWithChildren, ReactNode } from 'react'
import { useParams } from 'common'
import { Markdown } from 'components/interfaces/Markdown'
import { useDatabaseExtensionsQuery } from 'data/database-extensions/database-extensions-query'
import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject'
import { Alert_Shadcn_, AlertDescription_Shadcn_, Badge, Separator } from 'ui'
import { INTEGRATIONS } from '../Landing/Integrations.constants'
import { BuiltBySection } from './BuildBySection'
import { MarkdownContent } from './MarkdownContent'
import { MissingExtensionAlert } from './MissingExtensionAlert'
interface IntegrationOverviewTabProps {
actions?: ReactNode
}
export const IntegrationOverviewTab = ({
actions,
children,
}: PropsWithChildren<IntegrationOverviewTabProps>) => {
const { id } = useParams()
const router = useRouter()
const { data: project } = useSelectedProjectQuery()
const integration = INTEGRATIONS.find((i) => i.id === id)
const { data: extensions } = useDatabaseExtensionsQuery({
projectRef: project?.ref,
connectionString: project?.connectionString,
})
if (!integration) {
return <div>Unsupported integration type</div>
}
const dependsOnExtension = (integration.requiredExtensions ?? []).length > 0
const installableExtensions = (extensions ?? []).filter((ext) =>
(integration.requiredExtensions ?? []).includes(ext.name)
)
const hasToInstallExtensions = installableExtensions.some((x) => !x.installed_version)
// The integration requires extensions that are not available to install on the current database image
const hasMissingExtensions =
installableExtensions.length !== integration.requiredExtensions.length
return (
<div className="flex flex-col gap-8 py-10">
<BuiltBySection integration={integration} />
{dependsOnExtension && (
<div className="px-4 md:px-10 max-w-4xl">
<Alert_Shadcn_ variant="default" className="bg-surface-200/25 border border-default">
<AlertDescription_Shadcn_ className="flex flex-col gap-y-2">
<Badge className="bg-surface-300 bg-opacity-100 flex items-center gap-x-2 w-max">
<img
alt="Supabase"
src={`${router.basePath}/img/supabase-logo.svg`}
className=" h-2.5 cursor-pointer rounded"
/>
<span>Postgres Module</span>
</Badge>
<Markdown
className="max-w-full"
content={`This integration uses the ${integration.requiredExtensions.map((x) => `\`${x}\``).join(', ')}
extension${integration.requiredExtensions.length > 1 ? 's' : ''} directly in your Postgres database.
${hasToInstallExtensions && !hasMissingExtensions ? `Install ${integration.requiredExtensions.length > 1 ? 'these' : 'this'} database extension${integration.requiredExtensions.length > 1 ? 's' : ''} to use ${integration.name} in your project.` : ''}
`}
/>
{hasMissingExtensions ? (
integration.missingExtensionsAlert
) : (
<div className="flex flex-row gap-x-2">
{installableExtensions.map((extension) => (
<MissingExtensionAlert key={extension.name} extension={extension} />
))}
</div>
)}
</AlertDescription_Shadcn_>
</Alert_Shadcn_>
</div>
)}
{!!actions && !hasToInstallExtensions && <div className="px-10 max-w-4xl">{actions}</div>}
<MarkdownContent key={integration.id} integrationId={integration.id} />
<Separator />
{children}
</div>
)
}