Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate the Demo to Typescript #4081

Merged
merged 9 commits into from
Dec 3, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;
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' },
});
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