import { PermissionAction } from '@supabase/shared-types/out/constants' import { useQueryClient } from '@tanstack/react-query' import { isEmpty } from 'lodash' import Link from 'next/link' import { useRouter } from 'next/router' import { useState } from 'react' import toast from 'react-hot-toast' import { useParams } from 'common' import { useProjectContext } from 'components/layouts/ProjectLayout/ProjectContext' import { FormActions, FormPanel, FormSection, FormSectionContent, FormSectionLabel, FormsContainer, } from 'components/ui/Forms' import { invalidateSchemasQuery } from 'data/database/schemas-query' import { useFDWCreateMutation } from 'data/fdw/fdw-create-mutation' import { useCheckPermissions } from 'hooks' import { Button, Form, IconArrowLeft, IconEdit, IconExternalLink, IconTrash, Input } from 'ui' import InputField from './InputField' import WrapperTableEditor from './WrapperTableEditor' import { WRAPPERS } from './Wrappers.constants' import { makeValidateRequired } from './Wrappers.utils' const CreateWrapper = () => { const formId = 'create-wrapper-form' const router = useRouter() const queryClient = useQueryClient() const { ref, type } = useParams() const { project } = useProjectContext() const canCreateWrapper = useCheckPermissions(PermissionAction.TENANT_SQL_ADMIN_WRITE, 'wrappers') const [newTables, setNewTables] = useState([]) const [isEditingTable, setIsEditingTable] = useState(false) const [selectedTableToEdit, setSelectedTableToEdit] = useState() const [formErrors, setFormErrors] = useState<{ [k: string]: string }>({}) const { mutate: createFDW, isLoading: isCreating } = useFDWCreateMutation({ onSuccess: () => { toast.success(`Successfully created ${wrapperMeta?.label} foreign data wrapper`) setNewTables([]) const hasNewSchema = newTables.some((table) => table.is_new_schema) if (hasNewSchema) invalidateSchemasQuery(queryClient, ref) router.push(`/project/${ref}/database/wrappers`) }, }) const wrapperMeta = WRAPPERS.find((wrapper) => wrapper.name === type) const initialValues = wrapperMeta !== undefined ? { wrapper_name: '', server_name: '', ...Object.fromEntries( wrapperMeta.server.options.map((option) => [option.name, option.defaultValue ?? '']) ), } : {} if (wrapperMeta === undefined) { return (

Unsupported wrapper type

The wrapper type {type} not supported by the dashboard. Head back to create a different wrapper.

) } const onUpdateTable = (values: any) => { setNewTables((prev) => { // if the new values have tableIndex, we are editing an existing table if (values.tableIndex !== undefined) { const tableIndex = values.tableIndex const newTables = [...prev] delete values.tableIndex newTables[tableIndex] = values return newTables } return [...prev, values] }) setIsEditingTable(false) setSelectedTableToEdit(undefined) } const onSubmit = async (values: any) => { const validate = makeValidateRequired(wrapperMeta.server.options) const errors: any = validate(values) const { wrapper_name } = values if (wrapper_name.length === 0) errors.name = 'Please provide a name for your wrapper' if (newTables.length === 0) errors.tables = 'Please add at least one table' if (!isEmpty(errors)) return setFormErrors(errors) createFDW({ projectRef: project?.ref, connectionString: project?.connectionString, wrapperMeta, formState: { ...values, server_name: `${wrapper_name}_server` }, tables: newTables, }) } return (

Back

Create a {wrapperMeta.label} Wrapper

{({ handleReset, values, initialValues }: any) => { const hasChanges = JSON.stringify(values) !== JSON.stringify(initialValues) return (
} > Wrapper Configuration}> 0 ? ( <> Your wrapper's server name will be{' '} {values.wrapper_name}_server ) : ( '' ) } /> {wrapperMeta.label} Configuration} > {wrapperMeta.server.options.map((option) => ( ))}

Foreign Tables

You can query your data from these foreign tables after the wrapper is created

} > {newTables.length === 0 ? (
) : (
{newTables.map((table, i) => (

{table.schema_name}.{table.table_name}

{wrapperMeta.tables[table.index].label}:{' '} {table.columns.map((column: any) => column.name).join(', ')}

))}
)} {newTables.length > 0 && (
)} {newTables.length === 0 && formErrors.tables && (

{formErrors.tables}

)}
) }} { setSelectedTableToEdit(undefined) setIsEditingTable(false) }} onSave={onUpdateTable} initialData={selectedTableToEdit} />
) } export default CreateWrapper