├── .gitignore
├── README.md
├── package.json
├── public
├── favicon.ico
├── index.html
├── logo192.png
├── logo512.png
├── manifest.json
└── robots.txt
├── src
├── App.css
├── App.tsx
├── get-app.tsx
├── index.css
├── index.tsx
├── logo.svg
├── ra-data-hasura-graphql.d.ts
├── ra-data-hasura.d.ts
├── react-admin.d.ts
├── react-app-env.d.ts
├── service-worker.ts
├── todos.tsx
└── users.tsx
└── tsconfig.json
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # React Admin Low Code
2 |
3 | This is an example [react-admin](https://marmelab.com/react-admin/) application (configuration based CRUD admin UI builder) demonstrating how to use the [ra-data-hasura](https://github.com/hasura/ra-data-hasura) data provider with a [Hasura](https://hasura.io/) (automatic GraphQL API backend on top of PostgreSQL). By combining these two technologies, you can build an entire back office admin suite in a matter of hours.
4 |
5 | Video Tutorial: [Building Admin Interfaces with React Admin and Hasura GraphQL](https://www.youtube.com/watch?v=vVdV_LrBFqw)
6 |
7 | ⚠️ **NOTE** the [ra-data-hasura-graphql](https://github.com/Steams/ra-data-hasura-graphql) repository is now depreciated and has been migrated to the offical Hasura organization. Hasura has adopted and now maintains this library. Going forward, use this library: https://github.com/hasura/ra-data-hasura
8 |
9 | ## Alternatives
10 |
11 | [@dvasdekis](https://github.com/dvasdekis) has taken this concept a step further and integrated Docker Compose for development, Firebase for authentication and Flyway for database migrations.
12 |
13 | Check it out here: [react-admin-hasura-firebase](https://github.com/dvasdekis/react-admin-hasura-firebase)
14 |
15 | [@hgiasac](hgiasac) has also put together a very complete example with TypeScript. He's created several branches demonstrating auth with [jtw](https://github.com/hgiasac/ra-hasura-typescript-boilerplate/tree/auth-jwt) and [firebase](https://github.com/hgiasac/ra-hasura-typescript-boilerplate/tree/auth-firebase) as well as a backend that includes Hasura Actions and Events and auth:
16 |
17 | - [ra-hasura-typescript-boilerplate](https://github.com/hgiasac/ra-hasura-typescript-boilerplate)
18 | - [hasura-typescript-boilerplate](https://github.com/hgiasac/hasura-typescript-boilerplate)
19 |
20 | ## Available Scripts
21 |
22 | In the project directory, you can run:
23 |
24 | ### `yarn install`
25 |
26 | Install dependencies.
27 |
28 | ### `yarn start`
29 |
30 | Runs the app in the development mode.
31 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
32 |
33 | The page will reload if you make edits.
34 | You will also see any lint errors in the console.
35 |
36 | ### `yarn test`
37 |
38 | Launches the test runner in the interactive watch mode.
39 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
40 |
41 | ### `yarn build`
42 |
43 | Builds the app for production to the `build` folder.
44 | It correctly bundles React in production mode and optimizes the build for the best performance.
45 |
46 | The build is minified and the filenames include the hashes.
47 | Your app is ready to be deployed!
48 |
49 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
50 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "low-code-react-admin",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@material-ui/core": "^4.12.4",
7 | "@material-ui/icons": "^4.11.3",
8 | "@testing-library/jest-dom": "^5.16.5",
9 | "@testing-library/react": "^13.3.0",
10 | "@testing-library/user-event": "^14.4.3",
11 | "apollo-client": "^2.6.10",
12 | "eslint": "^8.21.0",
13 | "ra-core": "^4.2.7",
14 | "ra-data-hasura": "^0.5.2",
15 | "react": "^18.2.0",
16 | "react-admin": "^4.2.7",
17 | "react-dom": "^18.2.0",
18 | "react-router-dom": "^6.3.0",
19 | "react-scripts": "^5.0.1",
20 | "webpack": "^5.74.0"
21 | },
22 | "scripts": {
23 | "start": "react-scripts start",
24 | "build": "react-scripts build",
25 | "test": "react-scripts test",
26 | "eject": "react-scripts eject"
27 | },
28 | "eslintConfig": {
29 | "extends": "react-app"
30 | },
31 | "browserslist": {
32 | "production": [
33 | ">0.2%",
34 | "not dead",
35 | "not op_mini all"
36 | ],
37 | "development": [
38 | "last 1 chrome version",
39 | "last 1 firefox version",
40 | "last 1 safari version"
41 | ]
42 | },
43 | "devDependencies": {
44 | "@types/react": "^18.0.17",
45 | "@types/react-dom": "^18.0.6",
46 | "@types/react-router-dom": "^5.3.3",
47 | "typescript": "^4.7.4"
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cpursley/react-admin-low-code/44be8fe5bbb40656609dabc90d0b57d85df021dc/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | React Admin Low Code
28 |
29 |
30 |
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cpursley/react-admin-low-code/44be8fe5bbb40656609dabc90d0b57d85df021dc/public/logo192.png
--------------------------------------------------------------------------------
/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cpursley/react-admin-low-code/44be8fe5bbb40656609dabc90d0b57d85df021dc/public/logo512.png
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 |
--------------------------------------------------------------------------------
/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | }
8 |
9 | .App-header {
10 | background-color: #282c34;
11 | min-height: 100vh;
12 | display: flex;
13 | flex-direction: column;
14 | align-items: center;
15 | justify-content: center;
16 | font-size: calc(10px + 2vmin);
17 | color: white;
18 | }
19 |
20 | .App-link {
21 | color: #09d3ac;
22 | }
23 |
--------------------------------------------------------------------------------
/src/App.tsx:
--------------------------------------------------------------------------------
1 |
2 | import React from 'react';
3 | import { Admin, Resource } from 'react-admin';
4 | import { TodoList, TodoEdit, TodoCreate } from './todos';
5 | import { UserList, UserShow } from './users';
6 | import PostIcon from '@material-ui/icons/Book';
7 | import UserIcon from '@material-ui/icons/Group';
8 |
9 |
10 | type AppProps = {
11 | dataProvider: Function
12 | }
13 | function App(props: AppProps) {
14 |
15 | return (
16 |
19 |
26 |
32 |
33 | );
34 | };
35 |
36 | export default App;
37 |
--------------------------------------------------------------------------------
/src/get-app.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import App from './App'
3 | import buildHasuraProvider from 'ra-data-hasura';
4 |
5 | const uri = "https://react-admin-low-code.hasura.app/v1/graphql";
6 |
7 | export default async function getApp() {
8 | const provider = await buildHasuraProvider({
9 | clientOptions: { uri: uri }
10 | }); return () => (
11 |
12 | )
13 | }
14 |
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
4 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/src/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import './index.css';
3 | import getApp from './get-app'
4 | import * as serviceWorker from './service-worker';
5 | import ReactDOM from 'react-dom'
6 | import { BrowserRouter } from 'react-router-dom';
7 |
8 | getApp().then((App: React.FC) =>
9 | ReactDOM.render(
10 |
11 |
12 | ,
13 | document.getElementById('root')
14 | )
15 | );
16 |
17 |
18 |
19 | // If you want your app to work offline and load faster, you can change
20 | // unregister() to register() below. Note this comes with some pitfalls.
21 | // Learn more about service workers: https://bit.ly/CRA-PWA
22 | serviceWorker.unregister();
23 |
--------------------------------------------------------------------------------
/src/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/ra-data-hasura-graphql.d.ts:
--------------------------------------------------------------------------------
1 | declare module 'ra-data-hasura-graphql' {
2 | import * as apollo from 'apollo-client'
3 | export enum FetchType {
4 | GET_LIST = 'GET_LIST',
5 | GET_ONE = 'GET_ONE',
6 | GET_MANY = 'GET_MANY',
7 | GET_MANY_REFERENCE = 'GET_MANY_REFERENCE',
8 | CREATE = 'CREATE',
9 | UPDATE = 'UPDATE',
10 | UPDATE_MANY = 'UPDATE_MANY',
11 | DELETE = 'DELETE',
12 | DELETE_MANY = 'DELETE_MANY'
13 | }
14 |
15 | enum GraphqlTypeKind {
16 | SCALAR= 'SCALAR',
17 | OBJECT= 'OBJECT',
18 | INTERFACE = 'INTERFACE',
19 | UNION ='UNION',
20 | ENUM = 'ENUM',
21 | INPUT_OBJECT = 'INPUT_OBJECT',
22 | LIST ='LIST',
23 | NON_NULL ='NON_NULL'
24 | }
25 |
26 | type CheckExistsFunc = (s: string) => boolean
27 |
28 | type FetchActionsPaginated = FetchType.GET_MANY_REFERENCE | FetchType.GET_LIST
29 | type FetchMutateSingle = FetchType.CREATE | FetchType.UPDATE | FetchType.DELETE
30 | type FetchMutateBatch = FetchType.UPDATE_MANY | FetchType.DELETE_MANY
31 |
32 | type ResourceType = {
33 | name: string
34 | kind: GraphqlTypeKind,
35 | fields: IntrospectionField[]
36 | }
37 |
38 | export type IntrospectionResource = {
39 | [key in FetchType]?: InstrospectionQuery
40 | } & {
41 | type: ResourceType;
42 | };
43 |
44 |
45 | type IntrospectionField = {
46 | name: string,
47 | type: {
48 | kind: GraphqlTypeKind,
49 | ofType: {
50 | kind: GraphqlTypeKind,
51 | name: string
52 | }
53 | }
54 | }
55 |
56 | type InstrospectionQuery = {
57 | name: string,
58 | args: IntrospectionField[],
59 | type: GraphqlTypeKind
60 | }
61 |
62 | type IntrospectionType = {
63 | name: string
64 | kind: GraphqlTypeKind,
65 | }
66 |
67 | type IntrospectionResult = {
68 | resources: IntrospectionResource[],
69 | types: IntrospectionType[],
70 | fields: IntrospectionField[],
71 | queries: InstrospectionQuery[],
72 | schema: object
73 | }
74 |
75 | type IntrospectionOptions = {
76 | operationNames: {
77 | [k in FetchType]: (r: ResourceType) => string
78 | }
79 | exclude?: string[] | CheckExistsFunc
80 | include?: string[] | CheckExistsFunc
81 | }
82 |
83 |
84 | type BuildQuery = (f: FetchType, r: string, params: object) => {
85 | query: any,
86 | variables: object,
87 | parseResponse: ({ data }: any) => ({ data: any, total?: number })
88 | }
89 |
90 | type BuildFields = (type: ResourceType) => any[]
91 | type BuildMetaArgs = (q: InstrospectionQuery, v: object, aorFetchType: FetchType) => any[]
92 | type BuildArgs = (q: InstrospectionQuery, v: object) => any[]
93 | type BuildVariables = (r: ResourceType, aorFetchType: FetchType, params: object) => object
94 | type BuildGqlQuery = (i: IntrospectionResult, buildFields: BuildFields, buildMetaArgs: BuildMetaArgs, buildArgs: BuildArgs, buildApolloArgs: BuildArgs) => () => any
95 |
96 | type ResponseParser =
97 | ((i: IntrospectionResult) =>
98 | (f: FetchActionsPaginated) => ({ data }: any) => ({ data: object[], total: number })) |
99 | ((i: IntrospectionResult) => (f: FetchType.GET_MANY) => ({ data }: any) => ({ data: object[] })) |
100 | ((i: IntrospectionResult) => (f: FetchMutateSingle) => ({ data }: any) => ({ data: object })) |
101 | ((i: IntrospectionResult) => (f: FetchMutateBatch) => ({ data }: any) => ({ data: string[] }))
102 |
103 | export const buildFields: BuildFields
104 | export const buildMetaArgs: BuildMetaArgs
105 | export const buildArgs: BuildArgs
106 | export const buildApolloArgs: BuildArgs
107 | export const buildVariables: BuildVariables;
108 | export const buildGqlQuery: BuildGqlQuery;
109 |
110 | export function getResponseParser(i: IntrospectionResult): (f: FetchActionsPaginated) => ({ data }: any) => ({ data: object[], total: number })
111 | export function getResponseParser(i: IntrospectionResult): (f: FetchType.GET_MANY) => ({ data }: any) => ({ data: object[] })
112 | export function getResponseParser(i: IntrospectionResult): (f: FetchMutateSingle) => ({ data }: any) => ({ data: object })
113 | export function getResponseParser(i: IntrospectionResult): (f: FetchMutateBatch) => ({ data }: any) => ({ data: string[] })
114 | export function buildQueryFactory(buildVariables: BuildVariables, buildGqlQuery: BuildGqlQuery, getResponseParser: ResponseParser): BuildQuery
115 |
116 | type Options = {
117 | client?: apollo.ApolloClient,
118 | clientOptions?: {uri: string}
119 | introspection?: IntrospectionOptions
120 | }
121 |
122 | export default function (options: Options): Promise<(f: FetchType, r: ResourceType, params: object) => ({ data: any})>;
123 | }
--------------------------------------------------------------------------------
/src/ra-data-hasura.d.ts:
--------------------------------------------------------------------------------
1 | declare module "ra-data-hasura"
2 |
--------------------------------------------------------------------------------
/src/react-admin.d.ts:
--------------------------------------------------------------------------------
1 | declare module 'react-admin';
2 |
--------------------------------------------------------------------------------
/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/src/service-worker.ts:
--------------------------------------------------------------------------------
1 | // This optional code is used to register a service worker.
2 | // register() is not called by default.
3 |
4 | // This lets the app load faster on subsequent visits in production, and gives
5 | // it offline capabilities. However, it also means that developers (and users)
6 | // will only see deployed updates on subsequent visits to a page, after all the
7 | // existing tabs open on the page have been closed, since previously cached
8 | // resources are updated in the background.
9 |
10 | // To learn more about the benefits of this model and instructions on how to
11 | // opt-in, read https://bit.ly/CRA-PWA
12 |
13 | const isLocalhost = Boolean(
14 | window.location.hostname === 'localhost' ||
15 | // [::1] is the IPv6 localhost address.
16 | window.location.hostname === '[::1]' ||
17 | // 127.0.0.0/8 are considered localhost for IPv4.
18 | window.location.hostname.match(
19 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
20 | )
21 | );
22 |
23 | type Config = {
24 | onSuccess?: (registration: ServiceWorkerRegistration) => void;
25 | onUpdate?: (registration: ServiceWorkerRegistration) => void;
26 | };
27 |
28 | export function register(config?: Config) {
29 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
30 | // The URL constructor is available in all browsers that support SW.
31 | const publicUrl = new URL(
32 | process.env.PUBLIC_URL,
33 | window.location.href
34 | );
35 | if (publicUrl.origin !== window.location.origin) {
36 | // Our service worker won't work if PUBLIC_URL is on a different origin
37 | // from what our page is served on. This might happen if a CDN is used to
38 | // serve assets; see https://github.com/facebook/create-react-app/issues/2374
39 | return;
40 | }
41 |
42 | window.addEventListener('load', () => {
43 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
44 |
45 | if (isLocalhost) {
46 | // This is running on localhost. Let's check if a service worker still exists or not.
47 | checkValidServiceWorker(swUrl, config);
48 |
49 | // Add some additional logging to localhost, pointing developers to the
50 | // service worker/PWA documentation.
51 | navigator.serviceWorker.ready.then(() => {
52 | console.log(
53 | 'This web app is being served cache-first by a service ' +
54 | 'worker. To learn more, visit https://bit.ly/CRA-PWA'
55 | );
56 | });
57 | } else {
58 | // Is not localhost. Just register service worker
59 | registerValidSW(swUrl, config);
60 | }
61 | });
62 | }
63 | }
64 |
65 | function registerValidSW(swUrl: string, config?: Config) {
66 | navigator.serviceWorker
67 | .register(swUrl)
68 | .then(registration => {
69 | registration.onupdatefound = () => {
70 | const installingWorker = registration.installing;
71 | if (installingWorker == null) {
72 | return;
73 | }
74 | installingWorker.onstatechange = () => {
75 | if (installingWorker.state === 'installed') {
76 | if (navigator.serviceWorker.controller) {
77 | // At this point, the updated precached content has been fetched,
78 | // but the previous service worker will still serve the older
79 | // content until all client tabs are closed.
80 | console.log(
81 | 'New content is available and will be used when all ' +
82 | 'tabs for this page are closed. See https://bit.ly/CRA-PWA.'
83 | );
84 |
85 | // Execute callback
86 | if (config && config.onUpdate) {
87 | config.onUpdate(registration);
88 | }
89 | } else {
90 | // At this point, everything has been precached.
91 | // It's the perfect time to display a
92 | // "Content is cached for offline use." message.
93 | console.log('Content is cached for offline use.');
94 |
95 | // Execute callback
96 | if (config && config.onSuccess) {
97 | config.onSuccess(registration);
98 | }
99 | }
100 | }
101 | };
102 | };
103 | })
104 | .catch(error => {
105 | console.error('Error during service worker registration:', error);
106 | });
107 | }
108 |
109 | function checkValidServiceWorker(swUrl: string, config?: Config) {
110 | // Check if the service worker can be found. If it can't reload the page.
111 | fetch(swUrl, {
112 | headers: { 'Service-Worker': 'script' }
113 | })
114 | .then(response => {
115 | // Ensure service worker exists, and that we really are getting a JS file.
116 | const contentType = response.headers.get('content-type');
117 | if (
118 | response.status === 404 ||
119 | (contentType != null && contentType.indexOf('javascript') === -1)
120 | ) {
121 | // No service worker found. Probably a different app. Reload the page.
122 | navigator.serviceWorker.ready.then(registration => {
123 | registration.unregister().then(() => {
124 | window.location.reload();
125 | });
126 | });
127 | } else {
128 | // Service worker found. Proceed as normal.
129 | registerValidSW(swUrl, config);
130 | }
131 | })
132 | .catch(() => {
133 | console.log(
134 | 'No internet connection found. App is running in offline mode.'
135 | );
136 | });
137 | }
138 |
139 | export function unregister() {
140 | if ('serviceWorker' in navigator) {
141 | navigator.serviceWorker.ready
142 | .then(registration => {
143 | registration.unregister();
144 | })
145 | .catch(error => {
146 | console.error(error.message);
147 | });
148 | }
149 | }
150 |
--------------------------------------------------------------------------------
/src/todos.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {
3 | Filter,
4 | List,
5 | Edit,
6 | Create,
7 | Datagrid,
8 | TextField,
9 | ReferenceField,
10 | BooleanField,
11 | DateField,
12 | ReferenceInput,
13 | BooleanInput,
14 | SelectInput,
15 | SimpleForm,
16 | TextInput,
17 | TopToolbar,
18 | ListButton
19 | } from 'react-admin';
20 |
21 | const TodoFilter = (props: object) => (
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | );
30 |
31 | export const TodoList = (props: object) => (
32 |
} bulkActionButtons={false} {...props}>
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 | );
44 |
45 | const TodoTitle = ({ record }: { record?: {title: string}}) => {
46 | return Todo: {record ? `${record.title}` : ''};
47 | };
48 |
49 | const TodoEditActions = ({ basePath, data }: { basePath?: string, data?: object}) => (
50 |
51 |
52 |
53 | );
54 |
55 | export const TodoEdit = (props: object) => (
56 | } actions={} {...props}>
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 | );
67 |
68 | export const TodoCreate = (props: object) => (
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 | );
--------------------------------------------------------------------------------
/src/users.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {
3 | List,
4 | Filter,
5 | Datagrid,
6 | TextInput,
7 | TextField,
8 | DateField,
9 | BooleanField,
10 | Show,
11 | TabbedShowLayout,
12 | Tab,
13 | ReferenceManyField,
14 | TopToolbar,
15 | ListButton
16 | } from 'react-admin';
17 |
18 | const UserFilter = (props: object) => (
19 |
20 |
21 |
22 | );
23 |
24 | export const UserList = (props: object) => (
25 |
} bulkActionButtons={false} {...props}>
26 |
27 |
28 |
29 |
30 |
31 |
32 | );
33 |
34 | const UserTitle = ({ record }: { record?: {name: string}}) => {
35 | return User: {record ? `${record.name}` : ''};
36 | };
37 |
38 | const UserShowActions = ({ basePath, data }: { basePath?: string, data?: object}) => (
39 |
40 |
41 |
42 | );
43 |
44 | export const UserShow = (props: object) => (
45 | } actions={} {...props}>
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 | );
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": [
5 | "dom",
6 | "dom.iterable",
7 | "esnext"
8 | ],
9 | "allowJs": true,
10 | "skipLibCheck": true,
11 | "esModuleInterop": true,
12 | "allowSyntheticDefaultImports": true,
13 | "strict": true,
14 | "forceConsistentCasingInFileNames": true,
15 | "module": "esnext",
16 | "moduleResolution": "node",
17 | "resolveJsonModule": true,
18 | "noEmit": true,
19 | "jsx": "react",
20 | "isolatedModules": true
21 | },
22 | "include": [
23 | "src", "src/ra-data-hasura.d.ts"
24 | ]
25 | }
26 |
--------------------------------------------------------------------------------