Skip to content

Commit

Permalink
Merge pull request #4516 from josephktcheung/feature/demo-ts
Browse files Browse the repository at this point in the history
Convert demo example into typescript
  • Loading branch information
fzaninotto authored May 7, 2020
2 parents c23e6b5 + 56df98d commit 206ba77
Show file tree
Hide file tree
Showing 26 changed files with 481 additions and 249 deletions.
1 change: 1 addition & 0 deletions examples/demo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"not op_mini all"
],
"devDependencies": {
"@types/fetch-mock": "^7.3.2",
"@types/classnames": "^2.2.9",
"@types/jest": "^24.0.23",
"@types/node": "^12.12.14",
Expand Down
4 changes: 2 additions & 2 deletions examples/demo/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ const App = () => {

const fetchDataProvider = async () => {
restoreFetch = await fakeServerFactory(
process.env.REACT_APP_DATA_PROVIDER
process.env.REACT_APP_DATA_PROVIDER || ''
);
const dataProviderInstance = await dataProviderFactory(
process.env.REACT_APP_DATA_PROVIDER
process.env.REACT_APP_DATA_PROVIDER || ''
);
setDataProvider(
// GOTCHA: dataProviderInstance can be a function
Expand Down
1 change: 1 addition & 0 deletions examples/demo/src/data-generator-retail.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
declare module 'data-generator-retail';
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
import { ApolloQueryResult } from 'apollo-client';
import buildApolloClient, {
buildQuery as buildQueryFactory,
} from 'ra-data-graphql-simple';
import { DELETE } from 'ra-core';
import { DELETE, LegacyDataProvider } from 'ra-core';
import gql from 'graphql-tag';
const getGqlResource = resource => {
import {
IntrospectionField,
IntrospectionSchema,
IntrospectionType,
} from 'graphql';

const getGqlResource = (resource: string) => {
switch (resource) {
case 'customers':
return 'Customer';
Expand All @@ -28,7 +35,20 @@ const getGqlResource = resource => {
}
};

const customBuildQuery = introspectionResults => {
type IntrospectionResource = IntrospectionType & {
[key: string]: IntrospectionField;
};

interface IntrospectionResults {
types: IntrospectionType[];
queries: IntrospectionField[];
resources: IntrospectionResource[];
schema: IntrospectionSchema;
}

const customBuildQuery = (
introspectionResults: IntrospectionResults
): LegacyDataProvider => {
const buildQuery = buildQueryFactory(introspectionResults);

return (type, resource, params) => {
Expand All @@ -38,7 +58,7 @@ const customBuildQuery = introspectionResults => {
remove${resource}(id: $id)
}`,
variables: { id: params.id },
parseResponse: ({ data }) => {
parseResponse: ({ data }: ApolloQueryResult<any>) => {
if (data[`remove${resource}`]) {
return { data: { id: params.id } };
}
Expand All @@ -59,11 +79,17 @@ export default () => {
},
introspection: {
operationNames: {
[DELETE]: resource => `remove${resource.name}`,
[DELETE]: (resource: IntrospectionType) =>
`remove${resource.name}`,
},
},
buildQuery: customBuildQuery,
}).then(dataProvider => (type, resource, params) =>
dataProvider(type, getGqlResource(resource), params)
}).then(
(dataProvider: LegacyDataProvider) => (
...rest: Parameters<LegacyDataProvider>
) => {
const [type, resource, params] = rest;
return dataProvider(type, getGqlResource(resource), params);
}
);
};
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export default type => {
export default (type: string) => {
switch (type) {
case 'graphql':
return import('./graphql').then(factory => factory.default());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ const delayedDataProvider = new Proxy(restProvider, {
get: (target, name, self) =>
name === 'then' // as we await for the dataProvider, JS calls then on it. We must trap that call or else the dataProvider will be called with the then method
? self
: (resource, params) =>
: (resource: string, params: any) =>
new Promise(resolve =>
setTimeout(
() => resolve(restProvider[name](resource, params)),
() =>
resolve(
restProvider[name as string](resource, params)
),
500
)
),
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export default type => {
export default (type: string) => {
switch (type) {
case 'graphql':
return import('./graphql').then(factory => factory.default());
Expand Down
File renamed without changes.
1 change: 1 addition & 0 deletions examples/demo/src/fakerest.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
declare module 'fakerest';
1 change: 1 addition & 0 deletions examples/demo/src/json-graphql-server.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
declare module 'json-graphql-server';
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// in src/comments.js
import React from 'react';
import React, { FC } from 'react';
import Card from '@material-ui/core/Card';
import CardHeader from '@material-ui/core/CardHeader';
import CardContent from '@material-ui/core/CardContent';
Expand All @@ -14,6 +14,7 @@ import {
} from 'react-admin';

import CustomerReferenceField from '../visitors/CustomerReferenceField';
import { RecordMap, Identifier, Record } from 'ra-core';

const useListStyles = makeStyles(theme => ({
card: {
Expand All @@ -24,22 +25,33 @@ const useListStyles = makeStyles(theme => ({
},
cardTitleContent: {
display: 'flex',
flexDirection: 'rows',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
},
cardContent: theme.typography.body1,
cardContentRow: {
display: 'flex',
flexDirection: 'rows',
flexDirection: 'row',
alignItems: 'center',
margin: '0.5rem 0',
},
}));

const MobileGrid = ({ ids, data, basePath }) => {
interface MobileGridProps {
ids?: Identifier[];
data?: RecordMap<Record>;
basePath?: string;
}

const MobileGrid: FC<MobileGridProps> = ({ ids, data, basePath }) => {
const translate = useTranslate();
const classes = useListStyles();

if (!ids || !data || !basePath) {
return null;
}

return (
<div style={{ margin: '1em' }}>
{ids.map(id => (
Expand Down Expand Up @@ -88,7 +100,6 @@ const MobileGrid = ({ ids, data, basePath }) => {
record={data[id]}
source="total"
options={{ style: 'currency', currency: 'USD' }}
className={classes.total}
/>
</span>
<span className={classes.cardContentRow}>
Expand Down
13 changes: 0 additions & 13 deletions examples/demo/src/orders/NbItemsField.js

This file was deleted.

20 changes: 20 additions & 0 deletions examples/demo/src/orders/NbItemsField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React, { FC } from 'react';
import { FunctionField } from 'react-admin';
import { Order, FieldProps } from '../types';

const render = (record: Order) => record.basket.length;

interface NbItemsFieldProps extends FieldProps {
textAlign?: string;
}

const NbItemsField: FC<NbItemsFieldProps> = props => (
<FunctionField {...props} render={render} />
);

NbItemsField.defaultProps = {
label: 'Nb Items',
textAlign: 'right',
};

export default NbItemsField;
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { FC } from 'react';
import {
AutocompleteInput,
BooleanInput,
Expand All @@ -10,25 +10,30 @@ import {
useTranslate,
} from 'react-admin';
import { makeStyles } from '@material-ui/core/styles';
import { Order, Customer, EditComponentProps } from '../types';

import Basket from './Basket';

const OrderTitle = ({ record }) => {
interface OrderTitleProps {
record?: Order;
}

const OrderTitle: FC<OrderTitleProps> = ({ record }) => {
const translate = useTranslate();
return (
return record ? (
<span>
{translate('resources.commands.title', {
reference: record.reference,
})}
</span>
);
) : null;
};

const useEditStyles = makeStyles({
root: { alignItems: 'flex-start' },
});

const OrderEdit = props => {
const OrderEdit: FC<EditComponentProps> = props => {
const classes = useEditStyles();
return (
<Edit
Expand All @@ -41,7 +46,7 @@ const OrderEdit = props => {
<DateInput source="date" />
<ReferenceInput source="customer_id" reference="customers">
<AutocompleteInput
optionText={choice =>
optionText={(choice: Customer) =>
`${choice.first_name} ${choice.last_name}`
}
/>
Expand Down
Loading

0 comments on commit 206ba77

Please sign in to comment.