Postgraphile client for react-admin
Typescript API: https://bowlingx.github.io/ra-postgraphile/
$ yarn add ra-postgraphile / npm install ra-postgraphile --save
The ra-postgraphile data provider accepts 2 arguments:
client - The ApolloClient instance to use.
config - optional configuration
pgDataProvider(client, [config])
The following examples shows the basic usage:
import React, { useEffect, useState } from 'react'
import { Admin, Resource } from 'react-admin'
import { useApolloClient } from '@apollo/react-hooks'
import pgDataProvider from 'ra-postgraphile'
import { PostList, PostEdit, PostCreate } from './posts'
import { CommentList, CommentEdit, CommentCreate } from './posts'
const App = () => {
const [dataProvider, setDataProvider] = useState(null)
const client = useApolloClient()
useEffect(() => {
;(async () => {
const dataProvider = await pgDataProvider(client)
setDataProvider(() => dataProvider)
})()
}, [])
return (
dataProvider && (
<Admin dataProvider={dataProvider} layout={Layout}>
<Resource name="Posts" list={PostList} edit={PostEdit} create={PostCreate} />
<Resource name="Comments" list={CommentList} create={CommentCreate} edit={CommentEdit} />
</Admin>
)
)
}
export default App
The project has been tested only with the following plugins enabled on postgraphile:
There is limited support for the postgis plugin and not all input/query types are properly mapped.
const PgSimplifyInflectorPlugin = require('@graphile-contrib/pg-simplify-inflector')
const PgConnectionFilterPlugin = require('postgraphile-plugin-connection-filter')
Please see src/__test_utils/QueryRunner.ts for a minimal example setup.
For full-text search capabilities, the following plugin is also required:
const PostGraphileFulltextFilterPlugin = require('postgraphile-plugin-fulltext-filter')
You can pass an optional configuration object:
const pgDataProviderConfig: ProviderOptions = {
typeMap: {
YourType: {
expand: true,
},
},
}
typeMap - allows you to configure complex types and how they should be handled.
Please see (src/defaultTypeConfig.ts) for a default mapping.
Your config will be merged with the defaults.The following can be configured
| Option | Signature | Description |
|---|---|---|
queryValueToInputValue |
(value: any ) => any |
Allows you to map the value if used as an input type for mutations. Some values might not convert 1:1 if returned from the query and used as an input |
excludeFields |
string[] or ((fieldName: string, queryFetchType: FetchQueryType) => boolean) |
Allows you to exclude certain fields, either by passing an array (e.g. ['field1', 'field2']) or a function |
includeFields |
string[] or ((fieldName: string, queryFetchType: FetchQueryType) => boolean) |
Same as exclude fields, but if provided will let you dynamically decide if a field is queried. |
computeArgumentsForField |
(fieldName: string, args: ReadonlyArray<IntrospectionInputValue> ) => Record< string, any> or null |
Allows you to dynamically provide arguments for a given field |
expand |
boolean |
If true, will expand this type and query subfields |
pluralize |
(value: string ) => string |
Optional pluralization of resource name (uses pluralize by default) |
Please see (src/types.ts) for detailed types of TypeConfig.
If you require support for apollo-client v2 please use version <6, otherwise use >=6.
I recommend to upgrade to @apollo/client v3 packages because the core graphql data provider
requires version 3 in it's latest versions.
ra-postgraphile works on graphql types that are exposed by postgraphile.
We currently support the following constructs to query data:
TablesViewsFunctions with custom return type.Please see here for an example schema.
react-admin requires each resource to be identified by a unique id. If your resource does not
have an id field,
we alias the id field to your primaryKey. All types processed by ra-postgraphile require a
primary key.
The library will use the postgraphile-plugin-connection-filter filter property by default to apply
filters specified (e.g. for <List filters={...} />).
| Type | example filter |
|---|---|
string |
{ includes: 'value'} |
array |
{ in: [1,2,3] } |
numeric |
{ equalTo: 100 } |
boolean |
{ equalTo: true } |
...others |
{ equalTo: 'ENUM' } |
Multiple fields will then be merged with and and send to postgraphile e.g.:
{
"and": [
{
"field": {
"includes": "value"
}
}
]
}
To customize a filter, you have to provide a parse and format function to the actual input
Component. You can then customize the filter operation:
import type { FilterSpec } from 'ra-postgraphile'
const startsWithInsensitive = {
parse: (value: string): FilterSpec => {
return {
operator: 'startsWithInsensitive',
value,
}
},
format: (v: FilterSpec) => v?.value || '',
}
const Filters = (props: Record<string, unknown>) => (
<Filter {...props}>
<TextInput label="Search" source="name" alwaysOn {...startsWithInsensitive} />
</Filter>
)
This will then be transformed to
{
"and": [
{
"field": {
"startsWithInsensitive": "value"
}
}
]
}
It's also possible to define multiple filters per field to create nested filters
const filterThatFiltersMultipleFields = {
parse: (value: string) => ({
value: value
? [
{
firstKey: { every: { someReferenceId: { equalTo: value } } },
secondKey: { every: { someReferenceId: { equalTo: value } } },
},
]
: {},
key: 'or' /* can be or, and etc... */,
}),
format: (value: any) => value?.value?.[0]?.firstKey?.every?.someReferenceId?.equalTo,
}
This will be transformed to a filter like
{
"and": [
{
"or": [
{
"firstKey": {
"every": {
"someReferenceId": {
"equalTo": "value"
}
}
},
"secondKey": {
"every": {
"someReferenceId": {
"equalTo": "value"
}
}
}
}
]
}
]
}
We are using yarn for package management.
To run all tests you have to start the dependent postgres container with docker-compose up -d.
Generated using TypeDoc