import { useContext, FC, useEffect } from 'react'
import { indexOf } from 'lodash'
import { observer } from 'mobx-react-lite'
import { Input, Form, IconAlertCircle, InputNumber } from 'ui'
import { PermissionAction } from '@supabase/shared-types/out/constants'
import { checkPermissions, useStore } from 'hooks'
import { useParams } from 'common/hooks'
import { useProjectPostgrestConfigQuery } from 'data/config/project-postgrest-config-query'
import { useProjectPostgrestConfigUpdateMutation } from 'data/config/project-postgrest-config-update-mutation'
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 { ref: projectRef } = useParams()
const formId = 'project-postgres-config'
const { data: config, isError } = useProjectPostgrestConfigQuery({ projectRef })
const initialValues = {
db_schema: '',
max_rows: '',
db_extra_search_path: '',
}
const canUpdatePostgrestConfig = checkPermissions(
PermissionAction.UPDATE,
'custom_config_postgrest'
)
const { mutateAsync: updatePostgrestConfig } = useProjectPostgrestConfigUpdateMutation()
const updateConfig = async (updatedConfig: typeof initialValues) => {
if (!projectRef) return
try {
await updatePostgrestConfig({
projectRef,
dbSchema: updatedConfig.db_schema,
maxRows: updatedConfig.max_rows,
dbExtraSearchPath: updatedConfig.db_extra_search_path,
})
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 (
}
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)