Skip to content

Commit f0e45f7

Browse files
committed
Merge branch 'master' into next
2 parents 8cee866 + a0f243c commit f0e45f7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+3115
-269
lines changed

.eslintignore

+1
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ node_modules
22
build
33
lib
44
esm
5+
prism.js

CHANGELOG.md

+23
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,29 @@
2929

3030
* Failed (and unpublished) release
3131

32+
## v2.9.8
33+
34+
* Rewrite `ra-tree`. The new API isn't backwards compatible, but as ra-tree is considered a "lab" feature, we chose to release it in a minor version. ([3771](https://github.com/marmelab/react-admin/pull/3771)) ([djhi](https://github.com/djhi))
35+
* Add support for custom queries in `ra-data-graphql` ([3839](https://github.com/marmelab/react-admin/pull/3839)) ([djhi](https://github.com/djhi))
36+
* Add theme support in `FileInput` dropzone background ([3823](https://github.com/marmelab/react-admin/pull/3823)) ([despatates](https://github.com/despatates))
37+
* Add link to OpenID Connect advanced example ([3795](https://github.com/marmelab/react-admin/pull/3795)) ([Kmaschta](https://github.com/Kmaschta))
38+
* Fix react-admin dependency in secondary packages ([3791](https://github.com/marmelab/react-admin/pull/3791)) ([manelpb](https://github.com/manelpb))
39+
* Fix trailing slash in url breaks routing ([3788](https://github.com/marmelab/react-admin/pull/3788)) ([djhi](https://github.com/djhi))
40+
* Fix jsDoc in `refresh` side effect ([3780](https://github.com/marmelab/react-admin/pull/3780)) ([gillesdemey](https://github.com/gillesdemey))
41+
* Fix autocomplete of Password field on `LoginForm` ([3666](https://github.com/marmelab/react-admin/pull/3666)) ([UltimateForm](https://github.com/UltimateForm))
42+
43+
## v2.9.7
44+
45+
* Fix missing semicolons in docs ([3773](https://github.com/marmelab/react-admin/pull/3773)) ([emptyhand](https://github.com/emptyhand))
46+
* Fix typo in `ra-core` readme ([3772](https://github.com/marmelab/react-admin/pull/3772)) ([AlexanderOttenhoff](https://github.com/AlexanderOttenhoff))
47+
* Fix `dataProvider` doc uses onFailure instead of onError ([3761](https://github.com/marmelab/react-admin/pull/3761)) ([mchaffotte](https://github.com/mchaffotte))
48+
* Fix `Content-Type` header added for non GET requests. ([3743](https://github.com/marmelab/react-admin/pull/3743)) ([clement-escolano](https://github.com/clement-escolano))
49+
* Fix filter extend order in `ReferenceInputController` ([3740](https://github.com/marmelab/react-admin/pull/3740)) ([TheHyphen](https://github.com/TheHyphen))
50+
* Fix `TabbedForm` does not detect errors when source is a path ([3711](https://github.com/marmelab/react-admin/pull/3711)) ([djhi](https://github.com/djhi))
51+
* Add support for GraphQL Interface type ([3692](https://github.com/marmelab/react-admin/pull/3692)) ([MichielDeMey](https://github.com/MichielDeMey))
52+
* Fix typo in exporter documentation ([3675](https://github.com/marmelab/react-admin/pull/3675)) ([fzaninotto](https://github.com/fzaninotto))
53+
* Fix Move built-in validators documentation order ([3363](https://github.com/marmelab/react-admin/pull/3363)) ([heyfife](https://github.com/heyfife))
54+
3255
## v3.0.0-beta.0
3356

3457
* Ensure Data Provider does not alter the original error ([3757](https://github.com/marmelab/react-admin/pull/3757)) ([djhi](https://github.com/djhi))

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
A frontend Framework for building admin applications running in the browser on top of REST/GraphQL APIs, using ES6, [React](https://facebook.github.io/react/) and [Material Design](https://material.io/). Previously named [admin-on-rest](https://github.com/marmelab/admin-on-rest). Open sourced and maintained by [marmelab](https://marmelab.com/).
44

5-
[Demo](https://marmelab.com/react-admin-demo/) - [Documentation](https://marmelab.com/react-admin/) - [News](https://marmelab.com/en/blog/#react-admin) - [Releases](https://github.com/marmelab/react-admin/releases) - [Support](http://stackoverflow.com/questions/tagged/react-admin)
5+
[Home page](https://marmelab.com/react-admin/) - [Documentation](https://marmelab.com/react-admin/Tutorial.html) - [Demo](https://marmelab.com/react-admin-demo/) - [Blog](https://marmelab.com/en/blog/#react-admin) - [Releases](https://github.com/marmelab/react-admin/releases) - [Support](http://stackoverflow.com/questions/tagged/react-admin)
66

77
[![react-admin-demo](https://marmelab.com/react-admin/img/react-admin-demo-still.png)](https://vimeo.com/268958716)
88

docs/Actions.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ Fetching data is called a *side effect*, since it calls the outside world, and i
283283

284284
## Handling Side Effects In Other Hooks
285285

286-
But the other hooks presented in this chapter, starting with `useMutation`, don't expose the `dataProvider` Promise. To allow for side effects with these hooks, they all accept an additional `options` argument. It's an object with `onSuccess` and `onFailure` functions, that react admin executes on success... or on failure.
286+
But the other hooks presented in this chapter, starting with `useMutation`, don't expose the `dataProvider` Promise. To allow for side effects with these hooks, they all accept an additional `options` argument. It's an object with `onSuccess` and `onFailure` functions, that react-admin executes on success... or on failure.
287287

288288
So the `<ApproveButton>` written with `useMutation` instead of `useDataProvider` can specify side effects as follows:
289289

docs/AdvancedTutorials.md

+7
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,10 @@ This article shows how you can customize many parts of the framework without rep
5858

5959
* [Article](https://marmelab.com/blog/2019/03/27/supplying-your-own-defaults-to-react-admin.html)
6060
* [Codesandbox](https://codesandbox.io/s/qzxx4mjl59)
61+
62+
## OpenID Connect Authentication with React Admin
63+
64+
![OpenID Connect on React Admin with a button "Login With Google"](/img/openid-connect-example.png)
65+
66+
* [Live Example](https://marmelab.com/ra-example-oauth)
67+
* [Code Repository](https://github.com/marmelab/ra-example-oauth)

docs/CreateEdit.md

+61-60
Original file line numberDiff line numberDiff line change
@@ -543,9 +543,68 @@ export const UserCreate = (props) => (
543543
544544
**Tip**: The props you pass to `<SimpleForm>` and `<TabbedForm>` are passed to the `<Form>` of `react-final-form`.
545545
546-
### Per Input Validation: Function Validator
546+
### Per Input Validation: Built-in Field Validators
547+
548+
Alternatively, you can specify a `validate` prop directly in `<Input>` components, taking either a function, or an array of functions. React-admin already bundles a few validator functions, that you can just require, and use as input-level validators:
549+
550+
* `required(message)` if the field is mandatory,
551+
* `minValue(min, message)` to specify a minimum value for integers,
552+
* `maxValue(max, message)` to specify a maximum value for integers,
553+
* `minLength(min, message)` to specify a minimum length for strings,
554+
* `maxLength(max, message)` to specify a maximum length for strings,
555+
* `number(message)` to check that the input is a valid number,
556+
* `email(message)` to check that the input is a valid email address,
557+
* `regex(pattern, message)` to validate that the input matches a regex,
558+
* `choices(list, message)` to validate that the input is within a given list,
559+
560+
Example usage:
561+
562+
```jsx
563+
import {
564+
required,
565+
minLength,
566+
maxLength,
567+
minValue,
568+
maxValue,
569+
number,
570+
regex,
571+
email,
572+
choices
573+
} from 'react-admin';
574+
575+
const validateFirstName = [required(), minLength(2), maxLength(15)];
576+
const validateEmail = email();
577+
const validateAge = [number(), minValue(18)];
578+
const validateZipCode = regex(/^\d{5}$/, 'Must be a valid Zip Code');
579+
const validateSex = choices(['m', 'f'], 'Must be Male or Female');
580+
581+
export const UserCreate = (props) => (
582+
<Create {...props}>
583+
<SimpleForm>
584+
<TextInput label="First Name" source="firstName" validate={validateFirstName} />
585+
<TextInput label="Email" source="email" validate={validateEmail} />
586+
<TextInput label="Age" source="age" validate={validateAge}/>
587+
<TextInput label="Zip Code" source="zip" validate={validateZipCode}/>
588+
<SelectInput label="Sex" source="sex" choices={[
589+
{ id: 'm', name: 'Male' },
590+
{ id: 'f', name: 'Female' },
591+
]} validate={validateSex}/>
592+
</SimpleForm>
593+
</Create>
594+
);
595+
```
596+
597+
**Tip**: If you pass a function as a message, react-admin calls this function with `{ args, value, values,translate, ...props }` as argument. For instance:
598+
599+
```jsx
600+
const message = ({ translate }) => translate('myroot.validation.email_invalid');
601+
const validateEmail = email(message);
602+
```
603+
604+
### Per Input Validation: Custom Function Validator
605+
606+
You can also define your own validator functions. These functions should return `undefined` when there is no error, or an error string.
547607
548-
Alternatively, you can specify a `validate` prop directly in `<Input>` components, taking either a function, or an array of functions. These functions should return `undefined` when there is no error, or an error string.
549608
550609
```jsx
551610
const required = (message = 'Required') =>
@@ -649,64 +708,6 @@ export const ProductEdit = ({ ...props }) => (
649708
650709
**Tip**: You can use *both* Form validation and input validation.
651710
652-
### Built-in Field Validators
653-
654-
React-admin already bundles a few validator functions, that you can just require, and use as input-level validators:
655-
656-
* `required(message)` if the field is mandatory,
657-
* `minValue(min, message)` to specify a minimum value for integers,
658-
* `maxValue(max, message)` to specify a maximum value for integers,
659-
* `minLength(min, message)` to specify a minimum length for strings,
660-
* `maxLength(max, message)` to specify a maximum length for strings,
661-
* `number(message)` to check that the input is a valid number,
662-
* `email(message)` to check that the input is a valid email address,
663-
* `regex(pattern, message)` to validate that the input matches a regex,
664-
* `choices(list, message)` to validate that the input is within a given list,
665-
666-
Example usage:
667-
668-
```jsx
669-
import {
670-
required,
671-
minLength,
672-
maxLength,
673-
minValue,
674-
maxValue,
675-
number,
676-
regex,
677-
email,
678-
choices
679-
} from 'react-admin';
680-
681-
const validateFirstName = [required(), minLength(2), maxLength(15)];
682-
const validateEmail = email();
683-
const validateAge = [number(), minValue(18)];
684-
const validateZipCode = regex(/^\d{5}$/, 'Must be a valid Zip Code');
685-
const validateSex = choices(['m', 'f'], 'Must be Male or Female');
686-
687-
export const UserCreate = (props) => (
688-
<Create {...props}>
689-
<SimpleForm>
690-
<TextInput label="First Name" source="firstName" validate={validateFirstName} />
691-
<TextInput label="Email" source="email" validate={validateEmail} />
692-
<TextInput label="Age" source="age" validate={validateAge}/>
693-
<TextInput label="Zip Code" source="zip" validate={validateZipCode}/>
694-
<SelectInput label="Sex" source="sex" choices={[
695-
{ id: 'm', name: 'Male' },
696-
{ id: 'f', name: 'Female' },
697-
]} validate={validateSex}/>
698-
</SimpleForm>
699-
</Create>
700-
);
701-
```
702-
703-
**Tip**: If you pass a function as a message, react-admin calls this function with `{ args, value, values,translate, ...props }` as argument. For instance:
704-
705-
```jsx
706-
const message = ({ translate }) => translate('myroot.validation.email_invalid');
707-
const validateEmail = email(message);
708-
```
709-
710711
## Submit On Enter
711712
712713
By default, pressing `ENTER` in any of the form fields submits the form - this is the expected behavior in most cases. However, some of your custom input components (e.g. Google Maps widget) may have special handlers for the `ENTER` key. In that case, to disable the automated form submission on enter, set the `submitOnEnter` prop of the form component to `false`:

docs/DataProviders.md

+2
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,15 @@ Developers from the react-admin community have open-sourced Data Providers for m
7474
* **[HAL](http://stateless.co/hal_specification.html)**: [b-social/ra-data-hal](https://github.com/b-social/ra-data-hal)
7575
* **[Hasura](https://github.com/hasura/graphql-engine)**: [hasura/ra-data-hasura](https://github.com/hasura/graphql-engine/tree/master/community/tools/ra-data-hasura)
7676
* **[Hydra](http://www.hydra-cg.com/) / [JSON-LD](https://json-ld.org/)**: [api-platform/admin/hydra](https://github.com/api-platform/admin/blob/master/src/hydra/hydraClient.js)
77+
* **[IndexedDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API)**: [tykoth/ra-data-dexie](https://github.com/tykoth/ra-data-dexie)
7778
* **[JSON API](http://jsonapi.org/)**: [henvo/ra-jsonapi-client](https://github.com/henvo/ra-jsonapi-client)
7879
* **[JSON HAL](https://tools.ietf.org/html/draft-kelly-json-hal-08)**: [ra-data-json-hal](https://www.npmjs.com/package/ra-data-json-hal)
7980
* **[JSON server](https://github.com/typicode/json-server)**: [marmelab/ra-data-json-server](https://github.com/marmelab/ra-data-json-server).
8081
* **[Loopback](https://loopback.io/)**: [darthwesker/react-admin-loopback](https://github.com/darthwesker/react-admin-loopback)
8182
* **[NestJS CRUD](https://github.com/nestjsx/crud)**: [FusionWorks/react-admin-nestjsx-crud-dataprovider](https://github.com/FusionWorks/react-admin-nestjsx-crud-dataprovider)
8283
* **[Parse](https://parseplatform.org/)**: [almahdi/ra-data-parse](https://github.com/almahdi/ra-data-parse)
8384
* **[Prisma](https://github.com/weakky/ra-data-prisma)**: [weakky/ra-data-prisma](https://github.com/weakky/ra-data-prisma)
85+
* **[OpenCRUD](https://www.opencrud.org/)**: [weakky/ra-data-opencrud](https://github.com/Weakky/ra-data-opencrud)
8486
* **[REST-HAPI](https://github.com/JKHeadley/rest-hapi)**: [ra-data-rest-hapi](https://github.com/mkg20001/ra-data-rest-hapi)
8587
* **[Sails.js](https://sailsjs.com/)**: [mpampin/ra-data-json-sails](https://github.com/mpampin/ra-data-json-sails)
8688
* **[Spring Boot](https://spring.io/projects/spring-boot)**: [vishpat/ra-data-springboot-rest](https://github.com/vishpat/ra-data-springboot-rest)

docs/Ecosystem.md

+2-27
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ title: "Ecosystem"
2222

2323
## Translations
2424

25-
See the [translation](./Translation.md#available-locales) page.
25+
See the [Translation](./Translation.md#available-locales) page.
2626

2727
## Authentication Providers
2828

@@ -34,32 +34,7 @@ See the [translation](./Translation.md#available-locales) page.
3434

3535
## Data Providers
3636

37-
* **[Django Rest Framework](https://www.django-rest-framework.org/)**: [synaptic-cl/ra-data-drf](https://github.com/synaptic-cl/ra-data-drf)
38-
* **[Epilogue](https://github.com/dchester/epilogue)**: [dunghuynh/aor-epilogue-client](https://github.com/dunghuynh/aor-epilogue-client)
39-
* **[Feathersjs](http://www.feathersjs.com/)**: [josx/ra-data-feathers](https://github.com/josx/ra-data-feathers)
40-
* **[Firebase](https://firebase.google.com/docs/database)**: [aymendhaya/ra-data-firebase-client](https://github.com/aymendhaya/ra-data-firebase-client).
41-
* **[Firestore](https://firebase.google.com/docs/firestore)**: [rafalzawadzki/ra-data-firestore-client](https://github.com/rafalzawadzki/ra-data-firestore-client).
42-
* **[GraphCool](http://www.graph.cool/)**: [marmelab/ra-data-graphcool](https://github.com/marmelab/react-admin/tree/master/packages/ra-data-graphcool) (uses [Apollo](http://www.apollodata.com/))
43-
* **[GraphQL](http://graphql.org/)**: [marmelab/ra-data-graphql](https://github.com/marmelab/react-admin/tree/master/packages/ra-data-graphql) (uses [Apollo](http://www.apollodata.com/))
44-
* **[HAL](http://stateless.co/hal_specification.html)**: [b-social/ra-data-hal](https://github.com/b-social/ra-data-hal)
45-
* **[Hasura](https://github.com/hasura/graphql-engine)**: [hasura/ra-data-hasura](https://github.com/hasura/graphql-engine/tree/master/community/tools/ra-data-hasura)
46-
* **[Hydra](http://www.hydra-cg.com/) / [JSON-LD](https://json-ld.org/)**: [api-platform/admin/hydra](https://github.com/api-platform/admin/blob/master/src/hydra/hydraClient.js)
47-
* **[JSON API](http://jsonapi.org/)**: [henvo/ra-jsonapi-client](https://github.com/henvo/ra-jsonapi-client)
48-
* **[JSON HAL](https://tools.ietf.org/html/draft-kelly-json-hal-08)**: [ra-data-json-hal](https://www.npmjs.com/package/ra-data-json-hal)
49-
* **[JSON server](https://github.com/typicode/json-server)**: [marmelab/ra-data-json-server](https://github.com/marmelab/ra-data-json-server).
50-
* **[Loopback](http://loopback.io/)**: [kimkha/aor-loopback](https://github.com/kimkha/aor-loopback)
51-
* **[NestJS CRUD](https://github.com/nestjsx/crud)**: [FusionWorks/react-admin-nestjsx-crud-dataprovider](https://github.com/FusionWorks/react-admin-nestjsx-crud-dataprovider)
52-
* **[Parse Server](https://github.com/ParsePlatform/parse-server)**: [leperone/aor-parseserver-client](https://github.com/leperone/aor-parseserver-client)
53-
* **[Parse](https://parseplatform.org/)**: [almahdi/ra-data-parse](https://github.com/almahdi/ra-data-parse)
54-
* **[PostgREST](http://postgrest.com/en/v0.4/)**: [tomberek/aor-postgrest-client](https://github.com/tomberek/aor-postgrest-client)
55-
* **[Prisma](https://github.com/weakky/ra-data-prisma)**: [weakky/ra-data-prisma](https://github.com/weakky/ra-data-prisma)
56-
* **[REST-HAPI](https://github.com/JKHeadley/rest-hapi)**: [ra-data-rest-hapi](https://github.com/mkg20001/ra-data-rest-hapi)
57-
* **[Sails.js](https://sailsjs.com/)**: [mpampin/ra-data-json-sails](https://github.com/mpampin/ra-data-json-sails)
58-
* **[Spring Boot](https://spring.io/projects/spring-boot)**: [vishpat/ra-data-springboot-rest](https://github.com/vishpat/ra-data-springboot-rest)
59-
* **[Strapi](https://strapi.io/)**: [nazirov91/ra-strapi-rest](https://github.com/nazirov91/ra-strapi-rest)
60-
* **[Xmysql](https://github.com/o1lab/xmysql)**: [soaserele/aor-xmysql](https://github.com/soaserele/aor-xmysql)
61-
* Local JSON: [marmelab/ra-data-fakerest](https://github.com/marmelab/ra-data-fakerest)
62-
* Simple REST: [marmelab/ra-data-simple-rest](https://github.com/marmelab/ra-data-simple-rest).
37+
See the [Data Provider](./DataProviders.md#available-providers) page.
6338

6439
## UI
6540

docs/Inputs.md

+2-4
Original file line numberDiff line numberDiff line change
@@ -1404,10 +1404,8 @@ const OrderEdit = (props) => (
14041404
Would you need to update an input when another one changes, use the `useForm` hook from `react-final-form`. For example, a country input that resets a city input on change.
14051405
14061406
```jsx
1407-
1408-
import React, { Fragment } from 'react'
1409-
import { useForm } from 'react-final-form'
1410-
import { FormDataConsumer, REDUX_FORM_NAME } from 'react-admin';
1407+
import React, { Fragment } from 'react';
1408+
import { useForm } from 'react-final-form';
14111409

14121410
const OrderOrigin = ({ formData, ...rest }) => {
14131411
const form = useForm();

docs/List.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ import jsonExport from 'jsonexport/dist';
166166

167167
const exporter = posts => {
168168
const postsForExport = posts.map(post => {
169-
const { postForExport, backlinks, author } = post; // omit backlinks and author
169+
const { backlinks, author, ...postForExport } = post; // omit backlinks and author
170170
postForExport.author_name = post.author.name; // add a field
171171
return postForExport;
172172
});

0 commit comments

Comments
 (0)