import { useContext, FC, useEffect } from 'react' import { indexOf } from 'lodash' import { useRouter } from 'next/router' import { observer } from 'mobx-react-lite' import { Input, Form, IconAlertCircle, InputNumber } from 'ui' import { PermissionAction } from '@supabase/shared-types/out/constants' import { checkPermissions, useStore, useProjectPostgrestConfig } from 'hooks' import { API_URL } from 'lib/constants' import { patch } from 'lib/common/fetch' import MultiSelect from 'components/ui/MultiSelect' import { PageContext } from 'pages/project/[ref]/settings/api' import { FormActions, FormPanel, FormSection, FormSectionContent, FormSectionLabel, } from 'components/ui/Forms' interface Props {} const PostgrestConfig: FC = ({}) => { const PageState: any = useContext(PageContext) const { ui } = useStore() const { meta } = PageState const router = useRouter() const { ref } = router.query const formId = 'project-postgres-config' const { config, isError, isLoading } = useProjectPostgrestConfig(ref as string | undefined) const initialValues = { db_schema: '', max_rows: '', db_extra_search_path: '', } const canUpdatePostgrestConfig = checkPermissions( PermissionAction.UPDATE, 'custom_config_postgrest' ) const updateConfig = async (updatedConfig: any) => { try { const response = await patch(`${API_URL}/projects/${ref}/config/postgrest`, updatedConfig) if (response.error) { throw response.error } else { ui.setNotification({ category: 'success', message: 'Successfully saved settings' }) } } catch (error: any) { ui.setNotification({ error, category: 'error', message: `Failed to update config: ${error.message}`, }) } } const permanentSchema = ['public', 'storage'] const hiddenSchema = ['auth', 'pgbouncer', 'hooks', 'extensions'] const schema = meta.schemas .list( (x: any) => { const find = indexOf(hiddenSchema, x.name) if (find < 0) return x }, { allSchemas: true } ) .map((x: any) => { return { id: x.id, value: x.name, name: x.name, disabled: indexOf(permanentSchema, x.name) >= 0 ? true : false, } }) ?? [] return (
{}} onSubmit={updateConfig}> {({ isSubmitting, handleReset, resetForm, values, initialValues }: any) => { const hasChanges = JSON.stringify(values) !== JSON.stringify(initialValues) useEffect(() => { if (!isLoading && config) { const values = { db_schema: config.db_schema, max_rows: config.max_rows, db_extra_search_path: config.db_extra_search_path ?? '', } resetForm({ values, initialValues: values }) } }, [isLoading]) return ( <> API settings

} footer={
} > {isError ? (

Failed to retrieve API settings

) : ( <> Exposed schemas}> {schema.length >= 1 && ( The schemas to expose in your API. Tables, views and stored procedures in these schemas will get API endpoints. public and{' '} storage are protected by default. } emptyMessage={ <>

No schema available to choose

New schemas you create will appear here

} // value must be passed as array of strings value={(values?.db_schema ?? '').replace(/ /g, '').split(',')} // onChange returns array of strings onChange={(event) => { let updatedValues: any = values updatedValues.db_schema = event.join(', ') resetForm({ values: updatedValues, initialValues: updatedValues }) updateConfig({ ...updatedValues }) }} /> )}
Extra search path}> Max rows}> )}
) }}
) } export default observer(PostgrestConfig)