Skip to content

Commit

Permalink
Merge pull request #4081 from marmelab/demo-typescript
Browse files Browse the repository at this point in the history
Migrate the Demo to Typescript
  • Loading branch information
fzaninotto authored Dec 3, 2019
2 parents bdb6caa + 7c1185f commit a15f60a
Show file tree
Hide file tree
Showing 60 changed files with 562 additions and 320 deletions.
14 changes: 11 additions & 3 deletions examples/demo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@
"react-router-dom": "^5.1.0",
"react-scripts": "^3.0.0",
"recompose": "~0.26.0",
"redux-saga": "^1.0.0",
"source-map-explorer": "^2.0.0"
"redux-saga": "^1.0.0"
},
"scripts": {
"analyze": "source-map-explorer 'build/static/js/*.js'",
Expand All @@ -41,5 +40,14 @@
"not dead",
"not ie <= 10",
"not op_mini all"
]
],
"devDependencies": {
"@types/classnames": "^2.2.9",
"@types/jest": "^24.0.23",
"@types/node": "^12.12.14",
"@types/react": "^16.9.13",
"@types/react-dom": "^16.9.4",
"source-map-explorer": "^2.0.0",
"typescript": "^3.7.2"
}
}
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export default {
import { AuthProvider } from 'ra-core';

const authProvider: AuthProvider = {
login: ({ username }) => {
localStorage.setItem('username', username);
// accept all username/password combinations
Expand All @@ -13,3 +15,5 @@ export default {
localStorage.getItem('username') ? Promise.resolve() : Promise.reject(),
getPermissions: () => Promise.reject('Unknown method'),
};

export default authProvider;
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { FC } from 'react';
import {
Datagrid,
Edit,
Expand All @@ -7,23 +7,24 @@ import {
ReferenceManyField,
SimpleForm,
TextInput,
useTranslate,
} from 'react-admin';
import { useTranslate } from 'ra-core';

import ThumbnailField from '../products/ThumbnailField';
import ProductRefField from '../products/ProductRefField';
import { FieldProps, Category } from '../types';

const CategoryTitle = ({ record }) => {
const CategoryTitle: FC<FieldProps<Category>> = ({ record }) => {
const translate = useTranslate();
return (
return record ? (
<span>
{translate('resources.categories.name', { smart_count: 1 })} &quot;
{record.name}&quot;
</span>
);
) : null;
};

const CategoryEdit = props => (
const CategoryEdit = (props: any) => (
<Edit title={<CategoryTitle />} {...props}>
<SimpleForm>
<TextInput source="name" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Datagrid, EditButton, List, TextField } from 'react-admin';

import LinkToRelatedProducts from './LinkToRelatedProducts';

const CategoryList = ({ classes, ...props }) => (
const CategoryList = (props: any) => (
<List {...props} sort={{ field: 'name', order: 'ASC' }}>
<Datagrid>
<TextField source="name" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import React from 'react';
import React, { FC } from 'react';
import Button from '@material-ui/core/Button';
import { makeStyles } from '@material-ui/core/styles';
import { Link } from 'react-router-dom';
import { useTranslate } from 'react-admin';
import { stringify } from 'query-string';

import products from '../products';
import { FieldProps, Category } from '../types';

const useStyles = makeStyles({
icon: { paddingRight: '0.5em' },
Expand All @@ -15,10 +16,10 @@ const useStyles = makeStyles({
},
});

const LinkToRelatedProducts = ({ record }) => {
const LinkToRelatedProducts: FC<FieldProps<Category>> = ({ record }) => {
const translate = useTranslate();
const classes = useStyles();
return (
return record ? (
<Button
size="small"
color="primary"
Expand All @@ -38,7 +39,7 @@ const LinkToRelatedProducts = ({ record }) => {
<products.icon className={classes.icon} />
{translate('resources.categories.fields.products')}
</Button>
);
) : null;
};

export default LinkToRelatedProducts;
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import Button from '@material-ui/core/Button';
import { useTranslate, useLocale, useSetLocale, Title } from 'react-admin';
import { makeStyles } from '@material-ui/core/styles';
import { changeTheme } from './actions';
import { AppState } from '../types';

const useStyles = makeStyles({
label: { width: '10em', display: 'inline-block' },
Expand All @@ -17,7 +18,7 @@ const Configuration = () => {
const locale = useLocale();
const setLocale = useSetLocale();
const classes = useStyles();
const theme = useSelector(state => state.theme);
const theme = useSelector((state: AppState) => state.theme);
const dispatch = useDispatch();
return (
<Card>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { ThemeName } from '../types';

export const CHANGE_THEME = 'CHANGE_THEME';

export const changeTheme = theme => ({
export const changeTheme = (theme: ThemeName) => ({
type: CHANGE_THEME,
payload: theme,
});
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ import FullNameField from '../visitors/FullNameField';
import AddressField from '../visitors/AddressField';
import InvoiceShow from './InvoiceShow';

const ListFilters = props => (
const ListFilters = (props: any) => (
<Filter {...props}>
<DateInput source="date_gte" alwaysOn />
<DateInput source="date_lte" alwaysOn />
</Filter>
);

const InvoiceList = props => (
const InvoiceList = (props: any) => (
<List {...props} filters={<ListFilters />} perPage={25}>
<Datagrid rowClick="expand" expand={<InvoiceShow />}>
<TextField source="id" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,32 @@
import React from 'react';
import React, { FC } from 'react';
import Card from '@material-ui/core/Card';
import CardContent from '@material-ui/core/CardContent';
import Grid from '@material-ui/core/Grid';
import Typography from '@material-ui/core/Typography';
import { makeStyles } from '@material-ui/core/styles';
import { useShowController, ReferenceField, TextField } from 'react-admin';

import Basket from '../orders/Basket';
import { FieldProps, Customer } from '../types';

const CustomerField = ({ record }) => (
<Typography>
{record.first_name} {record.last_name}
<br />
{record.address}
<br />
{record.city}, {record.zipcode}
</Typography>
);
const CustomerField: FC<FieldProps<Customer>> = ({ record }) =>
record ? (
<Typography>
{record.first_name} {record.last_name}
<br />
{record.address}
<br />
{record.city}, {record.zipcode}
</Typography>
) : null;

const InvoiceShow = props => {
const InvoiceShow = (props: any) => {
const { record } = useShowController(props);
const classes = useStyles();

if (!record) return null;
return (
<Card style={{ width: 600, margin: 'auto' }}>
<Card className={classes.root}>
<CardContent>
<Grid container spacing={2}>
<Grid item xs={6}>
Expand All @@ -36,7 +41,7 @@ const InvoiceShow = props => {
</Grid>
</Grid>
<Grid container spacing={2}>
<Grid item xs={12} align="right">
<Grid item xs={12} alignContent="flex-end">
<ReferenceField
resource="invoices"
reference="customers"
Expand All @@ -49,7 +54,7 @@ const InvoiceShow = props => {
</ReferenceField>
</Grid>
</Grid>
<div style={{ height: 20 }}>&nbsp;</div>
<div className={classes.spacer}>&nbsp;</div>
<Grid container spacing={2}>
<Grid item xs={6}>
<Typography variant="h6" gutterBottom align="center">
Expand Down Expand Up @@ -81,7 +86,7 @@ const InvoiceShow = props => {
</ReferenceField>
</Grid>
</Grid>
<div style={{ margin: '10px 0' }}>
<div className={classes.invoices}>
<ReferenceField
resource="invoices"
reference="commands"
Expand All @@ -99,3 +104,9 @@ const InvoiceShow = props => {
};

export default InvoiceShow;

const useStyles = makeStyles({
root: { width: 600, margin: 'auto' },
spacer: { height: 20 },
invoices: { margin: '10px 0' },
});
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const useStyles = makeStyles({
},
});

const ConfigurationMenu = forwardRef((props, ref) => {
const ConfigurationMenu = forwardRef<any, any>((props, ref) => {
const translate = useTranslate();
return (
<MenuItemLink
Expand All @@ -31,13 +31,13 @@ const ConfigurationMenu = forwardRef((props, ref) => {
);
});

const CustomUserMenu = props => (
const CustomUserMenu = (props: any) => (
<UserMenu {...props}>
<ConfigurationMenu />
</UserMenu>
);

const CustomAppBar = props => {
const CustomAppBar = (props: any) => {
const classes = useStyles();
return (
<AppBar {...props} userMenu={<CustomUserMenu />}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ import { Layout, Sidebar } from 'react-admin';
import AppBar from './AppBar';
import Menu from './Menu';
import { darkTheme, lightTheme } from './themes';
import { AppState } from '../types';

const CustomSidebar = props => <Sidebar {...props} size={200} />;
const CustomSidebar = (props: any) => <Sidebar {...props} size={200} />;

export default props => {
const theme = useSelector(state =>
export default (props: any) => {
const theme = useSelector((state: AppState) =>
state.theme === 'dark' ? darkTheme : lightTheme
);
return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useState } from 'react';
import PropTypes from 'prop-types';
import { Field, Form } from 'react-final-form';
import { Field, withTypes } from 'react-final-form';

import Avatar from '@material-ui/core/Avatar';
import Button from '@material-ui/core/Button';
Expand All @@ -12,9 +12,10 @@ import { createMuiTheme, makeStyles } from '@material-ui/core/styles';
import { ThemeProvider } from '@material-ui/styles';
import LockIcon from '@material-ui/icons/Lock';

import { Notification, useTranslate, useLogin, useNotify } from 'react-admin';

import { Notification } from 'react-admin';
import { useTranslate, useLogin, useNotify } from 'ra-core';
import { lightTheme } from './themes';
import { Location } from 'history';

const useStyles = makeStyles(theme => ({
main: {
Expand Down Expand Up @@ -57,7 +58,7 @@ const useStyles = makeStyles(theme => ({
}));

const renderInput = ({
meta: { touched, error } = {},
meta: { touched, error } = { touched: false, error: undefined },
input: { ...inputProps },
...props
}) => (
Expand All @@ -70,17 +71,24 @@ const renderInput = ({
/>
);

const Login = ({ location }) => {
interface FormValues {
username?: string;
password?: string;
}

const { Form } = withTypes<FormValues>();

const Login = ({ location }: { location: Location }) => {
const [loading, setLoading] = useState(false);
const translate = useTranslate();
const classes = useStyles();
const notify = useNotify();
const login = useLogin();

const handleSubmit = auth => {
const handleSubmit = (auth: FormValues) => {
setLoading(true);
login(auth, location.state ? location.state.nextPathname : '/').catch(
error => {
(error: Error) => {
setLoading(false);
notify(
typeof error === 'string'
Expand All @@ -94,8 +102,8 @@ const Login = ({ location }) => {
);
};

const validate = values => {
const errors = {};
const validate = (values: FormValues) => {
const errors: FormValues = {};
if (!values.username) {
errors.username = translate('ra.validation.required');
}
Expand Down Expand Up @@ -126,6 +134,7 @@ const Login = ({ location }) => {
<Field
autoFocus
name="username"
// @ts-ignore
component={renderInput}
label={translate('ra.auth.username')}
disabled={loading}
Expand All @@ -134,6 +143,7 @@ const Login = ({ location }) => {
<div className={classes.input}>
<Field
name="password"
// @ts-ignore
component={renderInput}
label={translate('ra.auth.password')}
type="password"
Expand All @@ -147,7 +157,6 @@ const Login = ({ location }) => {
type="submit"
color="primary"
disabled={loading}
className={classes.button}
fullWidth
>
{loading && (
Expand Down Expand Up @@ -176,7 +185,7 @@ Login.propTypes = {
// We need to put the ThemeProvider decoration in another component
// Because otherwise the useStyles() hook used in Login won't get
// the right theme
const LoginWithTheme = props => (
const LoginWithTheme = (props: any) => (
<ThemeProvider theme={createMuiTheme(lightTheme)}>
<Login {...props} />
</ThemeProvider>
Expand Down
Loading

0 comments on commit a15f60a

Please sign in to comment.