Skip to content

Commit 69f2d0c

Browse files
committed
Merge branch 'master' into next
2 parents 71e2434 + 93e0f34 commit 69f2d0c

42 files changed

Lines changed: 487 additions & 236 deletions

File tree

Some content is hidden

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

CHANGELOG.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,34 @@
11
# Changelog
22

3+
## v4.10.2
4+
5+
* Fix custom redirect in pessimistic `<Edit>` or `<Create>` when using `warnWhenUnsavedChanges` ([#8882](https://github.com/marmelab/react-admin/pull/8882)) ([slax57](https://github.com/slax57))
6+
* Fix `create-react-admin` package manifest ([#8888](https://github.com/marmelab/react-admin/pull/8888)) ([djhi](https://github.com/djhi))
7+
* [Doc] Fix `<Menu.ResourceItem>` example should use the `name` prop ([#8886](https://github.com/marmelab/react-admin/pull/8886)) ([septentrion-730n](https://github.com/septentrion-730n))
8+
* [Doc] Update DataProvider List with `ra-strapi-rest` v4 ([#8865](https://github.com/marmelab/react-admin/pull/8865)) ([nazirov91](https://github.com/nazirov91))
9+
10+
## v4.10.1
11+
12+
* Republish all packages, including the `create-react-admin` installer ([fzaninotto](https://github.com/fzaninotto))
13+
14+
## v4.10.0
15+
16+
Note: This release wasn't published to npm, use version 4.10.1 or higher.
17+
18+
* Add `create-react-admin` installer ([#8833](https://github.com/marmelab/react-admin/pull/8833)) ([djhi](https://github.com/djhi))
19+
* Add `<InfiniteList>` and `<InfinitePagination>` components ([#8781](https://github.com/marmelab/react-admin/pull/8781)) ([fzaninotto](https://github.com/fzaninotto))
20+
* Add ability to change the sort, filter and selection of `<ArrayField>` ([#8802](https://github.com/marmelab/react-admin/pull/8802)) ([fzaninotto](https://github.com/fzaninotto))
21+
* Add ability to configure the remove icon of `<FileInputPreview>` ([#8756](https://github.com/marmelab/react-admin/pull/8756)) ([PennyJeans](https://github.com/PennyJeans))
22+
* Fix `<Datagrid>` does not apply `className` to its root element (minor BC) ([#8804](https://github.com/marmelab/react-admin/pull/8804)) ([slax57](https://github.com/slax57))
23+
* Fix `useHandleCallback` sometimes causes infinite redirection loop ([#8861](https://github.com/marmelab/react-admin/pull/8861)) ([djhi](https://github.com/djhi))
24+
* Fix `<AppBar alwaysOn>` hides sidebar menu on scroll ([#8856](https://github.com/marmelab/react-admin/pull/8856)) ([slax57](https://github.com/slax57))
25+
* Fix `<SimpleFormIterator>` new item's fields default empty string instead of null ([#8792](https://github.com/marmelab/react-admin/pull/8792)) ([kriskw1999](https://github.com/kriskw1999))
26+
* [Doc] Fix reference to Material UI ([#8857](https://github.com/marmelab/react-admin/pull/8857)) ([oliviertassinari](https://github.com/oliviertassinari))
27+
* [Doc] Fix Show documentation misses the `aside` prop ([#8855](https://github.com/marmelab/react-admin/pull/8855)) ([fzaninotto](https://github.com/fzaninotto))
28+
* [Doc] Convert GIF files to WebM ([#8767](https://github.com/marmelab/react-admin/pull/8767)) ([slax57](https://github.com/slax57))
29+
* [TypeScript] Add some utilities to improve generics ([#8815](https://github.com/marmelab/react-admin/pull/8815)) ([IAmVisco](https://github.com/IAmVisco))
30+
* [TypeScript] Improve `useRedirect` and `useCreatePath` types ([#8811](https://github.com/marmelab/react-admin/pull/8811)) ([djhi](https://github.com/djhi))
31+
332
## v4.9.4
433

534
* Fix GraphQL data provider when using different a custom credential type ([#8847](https://github.com/marmelab/react-admin/pull/8847)) ([@rlucia](https://github.com/rlucia))

cypress/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"private": true,
33
"name": "e2e",
4-
"version": "4.9.0",
4+
"version": "4.10.0",
55
"scripts": {
66
"start": "cypress open",
77
"test": "yarn node ./start.js"

docs/AuthProviderList.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,16 @@ title: "Supported Auth Provider Backends"
77

88
It's very common that your auth logic is so specific that you'll need to write your own `authProvider`. However, the community has built a few open-source Auth Providers that may fit your need:
99

10-
- **[Auth0](https://auth0.com/)**: [ra-auth-auth0](https://github.com/marmelab/ra-auth-auth0)
10+
- **[Auth0](https://auth0.com/)**: [marmelab/ra-auth-auth0](https://github.com/marmelab/ra-auth-auth0)
1111
- **[AWS Amplify](https://docs.amplify.aws)**: [MrHertal/react-admin-amplify](https://github.com/MrHertal/react-admin-amplify)
12-
- **[AWS Cognito](https://docs.aws.amazon.com/cognito/latest/developerguide/setting-up-the-javascript-sdk.html)**: [ra-auth-cognito](https://github.com/marmelab/ra-auth-cognito)
12+
- **[AWS Cognito](https://docs.aws.amazon.com/cognito/latest/developerguide/setting-up-the-javascript-sdk.html)**: [marmelab/ra-auth-cognito](https://github.com/marmelab/ra-auth-cognito)
13+
- **[Azure Active Directory (using MSAL)](https://github.com/AzureAD/microsoft-authentication-library-for-js/tree/dev/lib/msal-browser)**: [marmelab/ra-auth-msal](https://github.com/marmelab/ra-auth-msal)
14+
- **[Casdoor](https://casdoor.com/)**: [NMB-Lab/reactadmin-casdoor-authprovider](https://github.com/NMB-Lab/reactadmin-casdoor-authprovider)
1315
- **[Directus](https://directus.io/)**: [marmelab/ra-directus](https://github.com/marmelab/ra-directus)
1416
- **[Firebase Auth (Google, Facebook, GitHub, etc.)](https://firebase.google.com/docs/auth/web/firebaseui)**: [benwinding/react-admin-firebase](https://github.com/benwinding/react-admin-firebase#auth-provider)
17+
- **[Keycloak](https://www.keycloak.org/)**: [marmelab/ra-keycloak](https://github.com/marmelab/ra-keycloak)
1518
- **[Postgrest](https://postgrest.org/)**: [raphiniert-com/ra-data-postgrest](https://github.com/raphiniert-com/ra-data-postgrest)
1619
- **[Supabase](https://supabase.io/)**: [marmelab/ra-supabase](https://github.com/marmelab/ra-supabase)
17-
- **[Keycloak](https://www.keycloak.org/)**: [marmelab/ra-keycloak](https://github.com/marmelab/ra-keycloak)
18-
- **[Azure Active Directory (using MSAL)](https://github.com/AzureAD/microsoft-authentication-library-for-js/tree/dev/lib/msal-browser)**: [marmelab/ra-auth-msal](https://github.com/marmelab/ra-auth-msal)
1920
- **[SurrealDB](https://surrealdb.com/)**: [djedi23/ra-surrealdb](https://github.com/djedi23/ra-surrealdb)
2021

2122
Beyond ready-to-use providers, you may find help in these third-party tutorials about integrating more authentication backends:

docs/Count.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ If you need to count the number of records related to the current one via a one-
143143

144144
```jsx
145145
import {
146-
ChipField
146+
ChipField,
147147
Datagrid,
148148
DateField,
149149
List,

docs/CreateReactAdmin.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
---
2+
layout: default
3+
title: "The create-react-admin CLI"
4+
---
5+
6+
# `create-react-admin`
7+
8+
This CLI generates a new react-admin application using [Vite](https://vitejs.dev/). Use it by running the following command:
9+
10+
```sh
11+
npx create react-admin@latest your-admin-name
12+
# or
13+
yarn create react-admin your-admin-name
14+
```
15+
16+
It will then ask you to choose:
17+
- a data provider
18+
- a auth provider
19+
- the names of the resources to add
20+
- the package manager to use to install the dependencies
21+
22+
<video controls autoplay muted loop>
23+
<source src="./img/create-react-admin.webm" type="video/webm"/>
24+
Your browser does not support the video tag.
25+
</video>

docs/CustomRoutes.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,8 @@ import PeopleIcon from '@mui/icons-material/People';
143143
export const MyMenu = () => (
144144
<Menu>
145145
<Menu.DashboardItem />
146-
<Menu.ResourceItem to="/posts" />
147-
<Menu.ResourceItem to="/comments" />
146+
<Menu.ResourceItem name="posts" />
147+
<Menu.ResourceItem name="comments" />
148148
<Menu.Item to="/settings" primaryText="Users" leftIcon={<SettingsIcon />}/>
149149
<Menu.Item to="/profile" primaryText="Miscellaneous" leftIcon={<PeopleIcon />}/>
150150
</Menu>

docs/DataProviderList.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ If you can't find a Data Provider for your backend below, no worries! [Writing a
5757
* **[SQLite](https://www.sqlite.org/index.html)**: [marmelab/ra-sqlite-dataprovider](https://github.com/marmelab/ra-sqlite-dataprovider)
5858
* **[REST](https://en.wikipedia.org/wiki/Representational_state_transfer)**: [marmelab/ra-data-simple-rest](https://github.com/marmelab/react-admin/tree/master/packages/ra-data-simple-rest)
5959
* **[Spring Boot](https://spring.io/projects/spring-boot)**: [vishpat/ra-data-springboot-rest](https://github.com/vishpat/ra-data-springboot-rest)
60-
* **[Strapi v3](https://strapi.io/)**: [nazirov91/ra-strapi-rest](https://github.com/nazirov91/ra-strapi-rest)
60+
* **[Strapi v3/v4](https://strapi.io/)**: [nazirov91/ra-strapi-rest](https://github.com/nazirov91/ra-strapi-rest)
6161
* **[Strapi v4](https://strapi.io/)**: [garridorafa/ra-strapi-v4-rest](https://github.com/garridorafa/ra-strapi-v4-rest)
6262
* **[Supabase](https://supabase.io/)**: [marmelab/ra-supabase](https://github.com/marmelab/ra-supabase)
6363
- **[SurrealDB](https://surrealdb.com/)**: [djedi23/ra-surrealdb](https://github.com/djedi23/ra-surrealdb)

docs/FilteringTutorial.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -225,13 +225,13 @@ import {
225225
Datagrid,
226226
TextField,
227227
NumberField,
228-
ReferenceArrayField
228+
ReferenceArrayField,
229229
BooleanField,
230230
} from 'react-admin';
231231
import {
232232
textFilter,
233233
dateFilter,
234-
booleanFilter
234+
booleanFilter,
235235
referenceFilter,
236236
StackedFilters,
237237
} from '@react-admin/ra-form-layout';

docs/RealtimeDataProvider.md

Lines changed: 93 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,16 @@ title: "Realtime DataProvider Requirements"
55

66
# Realtime DataProvider Requirements
77

8+
`ra-realtime` provides helper functions to add real-time capabilities to an existing data provider if you use the following real-time backends:
9+
10+
- [Supabase](#supabase)
11+
- [API Platform](#api-platform)
12+
- [Mercure](#mercure)
13+
14+
For other backends, you'll need to write your own implementation. Check the [Writing a custom adapter](#writing-a-custom-adapter) section below for more information.
15+
16+
## Realtime Methods & Signature
17+
818
To enable real-time features, the `dataProvider` must implement three new methods:
919

1020
- `subscribe(topic, callback)`
@@ -20,7 +30,87 @@ In addition, to support the lock features, the `dataProvider` must implement 4 m
2030
- `getLock(resource, { id, meta })`
2131
- `getLocks(resource, { meta })`
2232

23-
## API-Platform Adapter
33+
## Supabase
34+
35+
The `ra-realtime` package contains a function augmenting a regular (API-based) `dataProvider` with real-time methods based on the capabilities of [Supabase](https://supabase.com/docs/guides/realtime).
36+
37+
This adapter subscribes to [Postgres Changes](https://supabase.com/docs/guides/realtime/extensions/postgres-changes), and transforms the events into the format expected by `ra-realtime`.
38+
39+
```jsx
40+
import { createClient } from '@supabase/supabase-js';
41+
import { supabaseDataProvider } from 'ra-supabase';
42+
import { addRealTimeMethodsBasedOnSupabase, ListLive } from '@react-admin/ra-realtime';
43+
import { Admin, Resource, Datagrid, TextField, EmailField } from 'react-admin';
44+
45+
const supabaseClient = createClient(
46+
process.env.SUPABASE_URL,
47+
process.env.SUPABASE_ANON_KEY
48+
);
49+
50+
const dataProvider = supabaseDataProvider({
51+
instanceUrl: process.env.SUPABASE_URL,
52+
apiKey: process.env.SUPABASE_ANON_KEY,
53+
supabaseClient
54+
});
55+
56+
const realTimeDataProvider = addRealTimeMethodsBasedOnSupabase({
57+
dataProvider,
58+
supabaseClient,
59+
});
60+
61+
export const App = () => (
62+
<Admin dataProvider={realTimeDataProvider}>
63+
<Resource name="sales" list={SaleList} />
64+
</Admin>
65+
);
66+
67+
const SaleList = () => (
68+
<ListLive>
69+
<Datagrid rowClick="edit">
70+
<TextField source="id" />
71+
<TextField source="first_name" />
72+
<TextField source="last_name" />
73+
<EmailField source="email" />
74+
</Datagrid>
75+
</ListLive>
76+
);
77+
```
78+
79+
**Tip:** Realtime features are not enabled in Supabase by default, you need to enable them. This can be done either from the [Replication](https://app.supabase.com/project/_/database/replication) section of your Supabase Dashboard, or by running the following SQL query with the [SQL Editor](https://app.supabase.com/project/_/sql):
80+
81+
```sql
82+
begin;
83+
84+
-- remove the supabase_realtime publication
85+
drop
86+
publication if exists supabase_realtime;
87+
88+
-- re-create the supabase_realtime publication with no tables
89+
create publication supabase_realtime;
90+
91+
commit;
92+
93+
-- add a table to the publication
94+
alter
95+
publication supabase_realtime add table sales;
96+
alter
97+
publication supabase_realtime add table contacts;
98+
alter
99+
publication supabase_realtime add table contactNotes;
100+
```
101+
102+
Have a look at the Supabase [Replication Setup](https://supabase.com/docs/guides/realtime/extensions/postgres-changes#replication-setup) documentation section for more info.
103+
104+
`addRealTimeMethodsBasedOnSupabase` accepts the following parameters:
105+
106+
| Prop | Required | Type | Default | Description |
107+
| ----------------- | -------- | ---------------- | ------- | -------------------------------------------------------- |
108+
| `dataProvider` | Required | `DataProvider` | - | The base dataProvider to augment with realtime methods |
109+
| `supabaseClient` | Required | `SupabaseClient` | - | The Supabase JS Client |
110+
111+
**Tip**: You may choose to sign your own tokens to customize claims that can be checked in your RLS policies. In order to use these custom tokens with `addRealTimeMethodsBasedOnSupabase`, you must pass an `apikey` field in both Realtime's `headers` and `params` when creating the `supabaseClient`. Please follow the instructions from the [Supabase documentation](https://supabase.com/docs/guides/realtime/extensions/postgres-changes#custom-tokens) for more information about how to do so.
112+
113+
## API-Platform
24114

25115
The `ra-realtime` package contains a function augmenting a regular (API-based) `dataProvider` with real-time methods based on the capabilities of [API-Platform](https://api-platform.com/). Use it as follows:
26116

@@ -70,7 +160,7 @@ const GreetingsList = () => (
70160
);
71161
```
72162

73-
## Mercure Adapter
163+
## Mercure
74164

75165
The `ra-realtime` package contains a function augmenting a regular (API-based) `dataProvider` with real-time methods based on [a Mercure hub](https://mercure.rocks/). Use it as follows:
76166

@@ -95,7 +185,7 @@ const App = () => (
95185

96186
If you're using another transport for real-time messages (WebSockets, long polling, GraphQL subscriptions, etc.), you'll have to implement `subscribe`, `unsubscribe`, and `publish` yourself in your `dataProvider`. As an example, here is an implementation using a local variable, that `ra-realtime` uses in tests:
97187

98-
```ts
188+
```jsx
99189
let subscriptions = [];
100190

101191
const dataProvider = {

docs/Tutorial.md

Lines changed: 13 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,24 @@ Here is an overview of the result:
1717

1818
## Setting Up
1919

20-
React-admin uses React. We'll use [Vite](https://vitejs.dev/) to create an empty React app, and install the `react-admin` package:
20+
React-admin uses React. We'll use [create-react-admin](https://github.com/marmelab/react-admin/tree/master/packages/create-react-admin) to bootstrap a new admin:
2121

2222
```sh
23-
yarn create vite test-admin --template react-ts
24-
cd test-admin/
25-
yarn add react-admin ra-data-json-server
23+
yarn create react-admin test-admin
24+
```
25+
26+
Choose **JSON Server** as the data provider, then **None** as the auth provider. Don't add any resource for now and just press **Enter**. Finally, choose either `npm` or `yarn` and press **Enter**. Once everything is installed, enter the following commands:
27+
28+
```sh
29+
cd test-admin
30+
npm run dev
31+
# or
2632
yarn dev
2733
```
2834

29-
You should be up and running with an empty React application on port 5173.
35+
You should be up and running with an empty React admin application on port 5173.
3036

31-
**Tip**: Although this tutorial uses a TypeScript template, you can use react-admin with JavaScript if you prefer. Also, you can use [create-react-app](./CreateReactApp.md), [Next.js](./NextJs.md), [Remix](./Remix.md), or any other React framework to create your admin app. React-admin is framework-agnostic.
37+
**Tip**: Although this tutorial uses a TypeScript template, you can use react-admin with JavaScript if you prefer. Also, you can use [Vite](https://vitejs.dev/), [create-react-app](./CreateReactApp.md), [Next.js](./NextJs.md), [Remix](./Remix.md), or any other React framework to create your admin app. React-admin is framework-agnostic.
3238

3339
## Using an API As Data Source
3440

@@ -70,57 +76,10 @@ JSONPlaceholder provides endpoints for users, posts, and comments. The admin we'
7076

7177
## Making Contact With The API Using a Data Provider
7278

73-
Bootstrap the admin app by replacing the `src/App.tsx` by the following code:
74-
75-
```jsx
76-
// in src/App.tsx
77-
import { Admin } from "react-admin";
78-
import jsonServerProvider from "ra-data-json-server";
79-
80-
const dataProvider = jsonServerProvider('https://jsonplaceholder.typicode.com');
81-
82-
const App = () => <Admin dataProvider={dataProvider} />;
83-
84-
export default App;
85-
```
86-
87-
That's enough for react-admin to render an empty app and confirm that the setup is done:
79+
The application has been initialized with enough code for react-admin to render an empty app and confirm that the setup is done:
8880

8981
[![Empty Admin](./img/tutorial_empty.png)](./img/tutorial_empty.png)
9082

91-
Also, you should change the default Vite CSS file to look like this:
92-
93-
```css
94-
/* in src/index.css */
95-
body {
96-
margin: 0;
97-
}
98-
```
99-
100-
Lastly, add the `Roboto` font to the `index.html` file:
101-
102-
```diff
103-
// in ./index.html
104-
<!DOCTYPE html>
105-
<html lang="en">
106-
<head>
107-
<meta charset="UTF-8" />
108-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
109-
<title>React Admin</title>
110-
+ <link
111-
+ rel="stylesheet"
112-
+ href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"
113-
+ />
114-
</head>
115-
<body>
116-
<div id="root"></div>
117-
<script type="module" src="/src/index.tsx"></script>
118-
</body>
119-
</html>
120-
```
121-
122-
**Tip:** You can also install the `Roboto` font locally by following the instructions from the [Material UI starter guide](https://mui.com/material-ui/getting-started/installation/#roboto-font).
123-
12483
The `<App>` component renders an `<Admin>` component, which is the root component of a react-admin application. This component expects a `dataProvider` prop - a function capable of fetching data from an API. Since there is no standard for data exchanges between computers, you will probably have to write a custom provider to connect react-admin to your own APIs - but we'll dive into Data Providers later. For now, let's take advantage of the `ra-data-json-server` data provider, which speaks the same REST dialect as JSONPlaceholder.
12584

12685
Now it's time to add features!

0 commit comments

Comments
 (0)