diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c91711a9ea2..4c2a4aec1d3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -111,7 +111,6 @@ jobs: e-commerce: runs-on: ubuntu-latest - if: github.ref_type != 'tag' needs: [typecheck] steps: - name: Checkout @@ -218,7 +217,7 @@ jobs: - name: Build create-react-admin run: make build-create-react-admin install - name: Create new project - run: ./node_modules/.bin/create-react-admin myadmin --data-provider ra-data-fakerest --auth-provider local-auth-provider --install npm + run: ./node_modules/.bin/create-react-admin myadmin --data-provider ra-data-fakerest --auth-provider local-auth-provider --resource posts --resource comments --install npm - name: Run the tests working-directory: ./myadmin run: npm run test diff --git a/CHANGELOG.md b/CHANGELOG.md index e66e2ffeb0b..b64099a4b7c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,21 @@ # Changelog +## 5.5.4 + +* Fix `` does not allow to clear filters ([#10522](https://github.com/marmelab/react-admin/pull/10522)) ([djhi](https://github.com/djhi)) +* Fix `create-react-admin` with `ra-data-fakerest` ignore custom resources ([#10502](https://github.com/marmelab/react-admin/pull/10502)) ([djhi](https://github.com/djhi)) +* Remove doc from published `react-admin` package ([#10505](https://github.com/marmelab/react-admin/pull/10505)) ([djhi](https://github.com/djhi)) +* [Doc] Backport `` and `` access control's doc ([#10521](https://github.com/marmelab/react-admin/pull/10521)) ([erwanMarmelab](https://github.com/erwanMarmelab)) +* [Doc] Backport `title={null}`'s doc on dialog components ([#10520](https://github.com/marmelab/react-admin/pull/10520)) ([erwanMarmelab](https://github.com/erwanMarmelab)) +* [Doc] Update doc to mention the dependency on `@ag-grid-community/styles` ([#10510](https://github.com/marmelab/react-admin/pull/10510)) ([erwanMarmelab](https://github.com/erwanMarmelab)) +* [Doc] Update `warnWhenUnsavedChanges`'s doc on dialog forms ([#10509](https://github.com/marmelab/react-admin/pull/10509)) ([erwanMarmelab](https://github.com/erwanMarmelab)) +* [Doc] Update docs to mention `format` prop for timezone adjustment ([#10506](https://github.com/marmelab/react-admin/pull/10506)) ([ogroppo](https://github.com/ogroppo)) +* [Doc] Add "Guides and Concepts" section ([#10477](https://github.com/marmelab/react-admin/pull/10477)) ([fzaninotto](https://github.com/fzaninotto)) +* [Doc] Deprecate mui v6 system props ([#10463](https://github.com/marmelab/react-admin/pull/10463)) ([smeng9](https://github.com/smeng9)) +* [Demo] Fix build ([#10499](https://github.com/marmelab/react-admin/pull/10499)) ([djhi](https://github.com/djhi)) +* [Chore] Rename directories for local storage data providers ([#10507](https://github.com/marmelab/react-admin/pull/10507)) ([erwanMarmelab](https://github.com/erwanMarmelab)) +* [Chore] Bump serialize-javascript from 6.0.1 to 6.0.2 ([#10508](https://github.com/marmelab/react-admin/pull/10508)) ([dependabot[bot]](https://github.com/apps/dependabot)) + ## 5.5.3 * Fix `useHandleCallback` compatibility with `React.StrictMode` ([#10486](https://github.com/marmelab/react-admin/pull/10486)) ([erwanMarmelab](https://github.com/erwanMarmelab)) diff --git a/cypress/support/LoginPage.js b/cypress/support/LoginPage.js index 1df9965a9cc..d626f8096cc 100644 --- a/cypress/support/LoginPage.js +++ b/cypress/support/LoginPage.js @@ -3,7 +3,7 @@ export default url => ({ appLoader: '.app-loader', username: "input[name='username']", password: "input[name='password']", - submitButton: 'button', + submitButton: "button[type='submit']", title: '#react-admin-title', }, diff --git a/docs/AppTheme.md b/docs/AppTheme.md index 9da8dc8126b..2f07e718c6a 100644 --- a/docs/AppTheme.md +++ b/docs/AppTheme.md @@ -106,11 +106,11 @@ const App = () => ( ## Built-In Themes -React-admin comes with 4 built-in themes, each one having a light and a dark variant. You can use them as a starting point for your custom theme, or use them as-is. +React-admin comes with 5 built-in themes, each one having a light and a dark variant. You can use them as a starting point for your custom theme, or use them as-is. -| :---: | :---: | -|    [Default](#default) [![Default light theme](./img/defaultLightTheme1.jpg)]((#default)) |    [Nano](#nano) [![Nano light theme](./img/nanoLightTheme1.jpg)](#nano) | -|    [Radiant](#radiant) [![Radiant light theme](./img/radiantLightTheme1.jpg)](#radiant) |    [House](#house) [![House light theme](./img/houseLightTheme1.jpg)](#house) | +|    [Default](#default) [![Default light theme](./img/defaultLightTheme1.jpg)]((#default)) |    [B&W](#bw) [![B&W light theme](./img/bwLightTheme1.jpg)](#bw) | +|    [Nano](#nano) [![Nano light theme](./img/nanoLightTheme1.jpg)](#nano) |    [Radiant](#radiant) [![Radiant light theme](./img/radiantLightTheme1.jpg)](#radiant) | +|    [House](#house) [![House light theme](./img/houseLightTheme1.jpg)](#house) | ### Default @@ -123,6 +123,37 @@ The default theme is a good fit for every application, and works equally well on You don't need to configure anything to use the default theme - it comes out of the box with react-admin. +### B&W + +A high-contrast theme with a black and white palette, ideal for visually impaired users. Its modern-looking style, reminiscent of shadcn, is suitable for desktop apps. + +[![B&W light theme](./img/bwLightTheme1.jpg)](./img/bwLightTheme1.jpg) +[![B&W light theme](./img/bwLightTheme2.jpg)](./img/bwLightTheme2.jpg) +[![B&W dark theme](./img/bwDarkTheme1.jpg)](./img/bwDarkTheme1.jpg) +[![B&W dark theme](./img/bwDarkTheme2.jpg)](./img/bwDarkTheme2.jpg) + +To use the B&W theme, import the `bwLightTheme` and `bwDarkTheme` objects, and pass them to the `` component: + +```jsx +import { Admin, bwLightTheme, bwDarkTheme } from 'react-admin'; + +export const App = () => ( + + // ... + +); +``` + +You must also import the Geist font in your `index.html` file: + +```html + +``` + ### Nano A dense theme with minimal chrome, ideal for complex apps. It uses a small font size, reduced spacing, text buttons, standard variant inputs, pale colors. Only fit for desktop apps. diff --git a/docs/Authentication.md b/docs/Authentication.md index cce0a9fb916..73d8104cfd8 100644 --- a/docs/Authentication.md +++ b/docs/Authentication.md @@ -29,13 +29,15 @@ const App = () => ( ); ``` +An `authProvider` is an object that handles authentication and authorization logic, similar to a `dataProvider`. It exposes methods that react-admin calls when needed, and you can also call these methods manually through specialized hooks. + Once an admin has an `authProvider`, react-admin will restrict CRUD pages (the `list`, `edit`, `create`, and `show` components of your `Resources`) to authenticated users and redirect anonymous users to the `/login` page, displaying a login form for a username and password. -## Anatomy Of An `authProvider` +![Login form](./img/login-form.png) -An `authProvider` is an object that handles authentication and authorization logic, similar to a `dataProvider`. It exposes methods that react-admin calls when needed, and you can also call these methods manually through specialized hooks. The `authProvider` methods must return a Promise. +React-admin offers several built-in `authProvider` implementations for popular authentication services like **Google Identity**, **Microsoft Entra ID**, **AWS Cognito**, **Auth0**, **Keycloak**, and others. Refer to the [List of Available Auth Providers](./AuthProviderList.md) to find one that suits your requirements. -A typical `authProvider` has the following methods: +If you need to implement a custom authentication strategy, the [Building Your Own Auth Provider](./AuthProviderWriting.md) offers a step-by-step guide. It boils down to implementing a few methods that react-admin calls when needed: ```js const authProvider = { @@ -54,8 +56,6 @@ const authProvider = { }; ``` -You can use an existing Auth Provider from the [List of Available Auth Providers](./AuthProviderList.md) or write your own by following the [Building Your Own Auth Provider](./AuthProviderWriting.md) instructions. - ## Sending Credentials To The API The `authProvider` handles authentication logic, but the `dataProvider` must include the user credentials in requests to the API. @@ -229,23 +229,74 @@ const App = () => ( ## Customizing The Login Component -Using an `authProvider` is enough to secure your app if authentication relies on a username and password. But for cases like using an email instead of a username, Single-Sign-On (SSO), or two-factor authentication, you can implement your own `LoginPage` component to be displayed under the `/login` route. +Using an `authProvider` is enough to secure your app if authentication relies on a username and password. But for cases like using an email instead of a username, Single-Sign-On (SSO), or two-factor authentication, you can use a custom login page by setting the [``](./Admin.md#loginpage) prop. -Pass this component to the [``](./Admin.md#loginpage) prop: +For example, to use an email field instead of a username field, use the `LoginWithEmail` component: -```jsx -// in src/App.js -import { Admin } from 'react-admin'; - -import MyLoginPage from './MyLoginPage'; +```tsx +import { Admin, LoginWithEmail } from 'react-admin'; +import authProvider from './authProvider'; const App = () => ( - - ... + + ... ); ``` +![Login with email](./img/LoginWithEmail.jpg) + +The default login page component is the `Login` component, which delegates the rendering of the login form to its child, usually a `LoginForm` component. This means you can create a custom login page by adding your own content to the `Login` component. + +For instance, to add a "forgot password" link to the login page: + +```jsx +import { Box, Link } from '@mui/material'; +import { Link as RouterLink } from 'react-router-dom'; +import { Login, LoginForm } from 'react-admin'; + +const MyLogin = () => ( + + + + + Forgot password? + + + +); +``` + +![Login with content](./img/LoginWithContent.jpg) + +You can also customize the login form fields, by setting the `LoginForm` children: + +```jsx +import { Link as RouterLink } from 'react-router-dom'; +import { Login, LoginForm, TextInput, PasswordInput, required } from 'react-admin'; + +const MyLogin = () => ( + + + + + + +); +``` + By default, the login page displays a gradient background. To change it, use the default Login component and pass an image URL as the `backgroundImage` prop. ```jsx @@ -257,7 +308,9 @@ const MyLoginPage = () => ( ); ``` -To build a Login page from scratch, use the [`useLogin` hook](./useLogin.md). +![Custom login page](./img/LoginCustomBackground.jpg) + +You can also build your login page from scratch, leveraging the [`useLogin` hook](./useLogin.md) to handle the login form submission. ```jsx // in src/MyLoginPage.js @@ -415,7 +468,7 @@ export const dataProvider = addRefreshAuthToDataProvider(baseDataProvider, refre ## Authorization -Access control and permissions allow you to restrict certain pages to specific users. React-admin provides powerful primitives for implementing authorization logic. For detailed guidance, check out the [Authorization](./Permissions.md) documentation. +Access control and permissions allow you to restrict certain pages and features to specific users. React-admin provides powerful primitives for implementing authorization logic. For detailed guidance, check out the [Authorization](./Permissions.md) documentation.