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

docs: Revamp API Platform Admin docs #2141

Open
wants to merge 32 commits into
base: 4.1
Choose a base branch
from
Open

docs: Revamp API Platform Admin docs #2141

wants to merge 32 commits into from

Conversation

slax57
Copy link

@slax57 slax57 commented Mar 7, 2025

This PR aims at generally improving the API Platform Admin documentation, notably:

  • Updating the code, links, and screenshots
  • Reorganizing the pages to provide a linear, guided read-through for newcomers (see below)
  • Improve documentation regarding the ways to customize the generated Admin, most notably showcasing advanced customization using React Admin components
  • Fix minor issues found while proof-reading

This PR relies on customization examples brought by api-platform/admin#600

Here is the new TOC I implemented:

  1. The API Platform Admin
    i. General intro about what API Platform Admin is
    ii. When can I use it
    iii. Introduce React Admin
    iv. Feature @fzaninotto 's presentation given at the API Platform Conference 2024
    v. List features offered by the Admin
  2. Getting Started
    i. Introduce HydraAdmin
    ii. Introduce OpenApiAdmin
  3. Customizing the Schema
    i. Show how to customize the Admin with just PHP changes
    ii. Includes the 'Using the Schema.org Vocabulary' content
  4. Customizing Guessers
    i. Learn how to use FieldGuesser and InputGuesser
    ii. Includes current section 'Customizing the Admin'
  5. Customizing the Admin
    i. Provide examples of more advanced customization, leveraging React Admin components
  6. Handling Relations
  7. Validating Forms
  8. Realtime Updates
  9. Authentication
  10. Handling File Upload
  11. Performance -> renamed to Performance Tips
  12. Components -> renamed to Components Reference

TODO

  • Finish the rewrite
  • update the menu
  • Much proof-reading

How to test

  1. Clone https://github.com/api-platform/docs-website
  2. Edit docs-versions.txt to add a version named revamp-admin-docs (name of the branch of this PR)
  3. Edit hugo.toml to add a version named revamp-admin-docs with path vrevamp-admin-docs
  4. Install hugo on your machine (sudo apt install hugo)
  5. Follow the instructions from the README.md of the docs-website repo
  6. Run hugo serve
  7. Browse http://localhost:1313/docs/vrevamp-admin-docs/admin/

@slax57 slax57 force-pushed the revamp-admin-docs branch from 1fca087 to 9dbcf96 Compare March 10, 2025 17:34
@slax57 slax57 changed the title [Doc] Revamp API Platform Admin docs docs: Revamp API Platform Admin docs Mar 12, 2025
Copy link

@fzaninotto fzaninotto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome work! Kudos for that.

The new chapters are 💯 . You helped improve the old ones, but some passages are still hard to follow.

@slax57 slax57 marked this pull request as ready for review March 14, 2025 18:20

Thanks to its built-in **guessers**, API Platform Admin parses the API documentation then uses React Admin to expose a nice, responsive management interface (Create-Retrieve-Update-Delete, i.e. CRUD) for all documented resource types.

Afterwards, you can **customize everything** by using the numerous components provided [React Admin](https://marmelab.com/react-admin/documentation.html) and [MUI](https://mui.com/), or even writing your own [React](https://reactjs.org/) components.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Afterwards, you can **customize everything** by using the numerous components provided [React Admin](https://marmelab.com/react-admin/documentation.html) and [MUI](https://mui.com/), or even writing your own [React](https://reactjs.org/) components.
Afterwards, you can **customize everything** by using the numerous components provided by [React Admin](https://marmelab.com/react-admin/documentation.html) and [MUI](https://mui.com/), or even writing your own [React](https://reactjs.org/) components.

```

**Tip:** if you don't want to hardcode the API URL, you can [use an environment variable](https://vite.dev/guide/env-and-mode).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This tip is only available if the user has used CRA, if the distribution is used it's Next.js instead (we should probably use Vite instead tough 😄).

@@ -0,0 +1,147 @@
# Customizing the Schema
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe the filename should just be schema.md.


## Adding Filtering Capabilities

You can add the [`ApiFilter` attribute](../core/filters.md#apifilter-attribute) to an Entity to configure a filter on a property.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
You can add the [`ApiFilter` attribute](../core/filters.md#apifilter-attribute) to an Entity to configure a filter on a property.
You can add the [`ApiFilter` attribute](../core/filters.md#apifilter-attribute) to an API Platform resource to configure a filter on a property.


You can add the [`ApiFilter` attribute](../core/filters.md#apifilter-attribute) to an Entity to configure a filter on a property.

For instance, here is how configure filtering on the `id`, `title` and `author` properties of a `Book` entity:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
For instance, here is how configure filtering on the `id`, `title` and `author` properties of a `Book` entity:
For instance, here is how configure filtering on the `id`, `title` and `author` properties of a `Book` resource:


## Adding Sorting Capabilities

You can also use the [`ApiFilter` attribute](../core/filters.md#apifilter-attribute) on an Entity to configure sorting.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
You can also use the [`ApiFilter` attribute](../core/filters.md#apifilter-attribute) on an Entity to configure sorting.
You can also use the [`ApiFilter` attribute](../core/filters.md#apifilter-attribute) on an API Plaform resource to configure sorting.


You can also use the [`ApiFilter` attribute](../core/filters.md#apifilter-attribute) on an Entity to configure sorting.

For instance, here is how to configure sorting on the `id`, `isbn`, `title`, `author` and `publicationDate` properties of a `Book` entity:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
For instance, here is how to configure sorting on the `id`, `isbn`, `title`, `author` and `publicationDate` properties of a `Book` entity:
For instance, here is how to configure sorting on the `id`, `isbn`, `title`, `author` and `publicationDate` properties of a `Book` resource:


By default, `<ResourceGuesser>` will render a `<ListGuesser>` component as the list view for a resource.

Again, this component will automatically introspect the API schema and generate a list view with all the fields of the resource.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Again, this component will automatically introspect the API schema and generate a list view with all the fields of the resource.
This component will automatically introspect the API schema and generate a list view with all the fields of the resource.


This is already usable, but may not provide the best user experience yet.

Here, too, to start customizing the list view, you can look at the DevTools console. You will see messages like this:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Here, too, to start customizing the list view, you can look at the DevTools console. You will see messages like this:
To start customizing the list view, you can look at the DevTools console. You will see messages like this:


## Customizing the `<ShowGuesser>`

Following the same principles (including looking at the DevTools console) we can customize the show view.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Following the same principles (including looking at the DevTools console) we can customize the show view.
Following the same principles as the `<ListGuesser>` (including looking at the DevTools console) we can customize the show view.


## Customizing the Edit Form
Again, we can start by looking at the DevTools console to get the initial code of the components.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Again, we can start by looking at the DevTools console to get the initial code of the components.
We can start by looking at the DevTools console to get the initial code of the components.


![Admin with customized edit guesser](./images/admin-custom-edit-guesser.png)

**Tip:** Here, we leveraged the `multiline` and `readOnly` props of the `<InputGuesser>` component. But you can use any [common input prop](https://marmelab.com/react-admin/Inputs.html#common-input-props) supported by react-admin [Inputs](https://marmelab.com/react-admin/Inputs.html) on them.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
**Tip:** Here, we leveraged the `multiline` and `readOnly` props of the `<InputGuesser>` component. But you can use any [common input prop](https://marmelab.com/react-admin/Inputs.html#common-input-props) supported by react-admin [Inputs](https://marmelab.com/react-admin/Inputs.html) on them.
**Tip:** Here, we leveraged the `multiline` and `readOnly` props of the `<InputGuesser>` component. But you can use any [common input prop](https://marmelab.com/react-admin/Inputs.html#common-input-props) supported by React Admin [Inputs](https://marmelab.com/react-admin/Inputs.html) on them.


![Admin with customized edit guesser](./images/admin-custom-edit-guesser.png)

**Tip:** Here, we leveraged the `multiline` and `readOnly` props of the `<InputGuesser>` component. But you can use any [common input prop](https://marmelab.com/react-admin/Inputs.html#common-input-props) supported by react-admin [Inputs](https://marmelab.com/react-admin/Inputs.html) on them.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
**Tip:** Here, we leveraged the `multiline` and `readOnly` props of the `<InputGuesser>` component. But you can use any [common input prop](https://marmelab.com/react-admin/Inputs.html#common-input-props) supported by react-admin [Inputs](https://marmelab.com/react-admin/Inputs.html) on them.
**Tip:** Here, we leveraged the `multiline` and `readOnly` props of the `<InputGuesser>` component. But you can use any [common input prop](https://marmelab.com/react-admin/Inputs.html#common-input-props) supported by React Admin [Inputs](https://marmelab.com/react-admin/Inputs.html) on them.


## Going Further
The above examples limit to customizing the various API Platform Admin Guessers, but this is just the tip of the iceberg.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The above examples limit to customizing the various API Platform Admin Guessers, but this is just the tip of the iceberg.
The above examples are limited to customizing the various API Platform Admin Guessers, but this is just the tip of the iceberg.


However the UX can often be improved by setting a default action when clicking on a row, and removing the `Show` and `Edit` buttons.

To hide these buttons, we will need to replace the `<ListGuesser>` by a [`<List>`](https://marmelab.com/react-admin/List.html) component, provided by `react-admin`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's too bad, I think this example is not really suited: we should be able to change the <ListGuesser> component to support removing its buttons.
It's the philosophy of API Platform Admin: making sure the user can customize simple things by keeping the guessers as most as possible.


If the user clicks on the undo button, the record will be restored to its previous state. Otherwise, the change is persisted to the API.

Let's, for instance, add the possibility to undo an update to a book. To do that, we will replace the generated `<EditGuesser>` by the [`<Edit>`](https://marmelab.com/react-admin/Edit.html) component, provided by `react-admin`. Undoable mutations are enabled by default for the `<Edit>` component.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as my previous comment, setting the mutationMode prop of <EditGuesser> is sufficient to do this.


When the user tries to navigate away from a form with unsaved changes, a confirmation dialog will be displayed, asking the user if they want to leave the page. This prevents the risk of losing unsaved data.

Reusing the `BookEdit` component from the previous example, all we need to do is to leverage the [`warnWhenUnsavedChanges`](https://marmelab.com/react-admin/SimpleForm.html#warnwhenunsavedchanges) prop of the `<SimpleForm>` component to enable this feature.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as my previous comments: this props is exposed by the <EditGuesser> component.


Speaking of tabbed layout, a common pattern is to display related records in a dedicated tab of the show view of the main record.

For instance, let's leverage the [`<TabbedShowLayout>`](https://marmelab.com/react-admin/TabbedShowLayout.html) component provided by `react-admin` to display the reviews of a book in a dedicated tab.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
For instance, let's leverage the [`<TabbedShowLayout>`](https://marmelab.com/react-admin/TabbedShowLayout.html) component provided by `react-admin` to display the reviews of a book in a dedicated tab.
For instance, let's leverage the [`<TabbedShowLayout>`](https://marmelab.com/react-admin/TabbedShowLayout.html) component provided by React Admin to display the reviews of a book in a dedicated tab.

import { Rating } from '@mui/material';

const ReviewShow = () => (
<Show>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not using the <ShowGuesser> component here?

Comment on lines +418 to +419
<Edit warnWhenUnsavedChanges>
<SimpleForm sx={{ maxWidth: 500 }}>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not using the <EditGuesser> component here?

- [SolarLayout](https://marmelab.com/react-admin/SolarLayout.html)
- And many more...

React Admin already includes 230+ hooks and components. And it always allow you to make your own, thanks to the building blocks it provides. Feel free to read through its [All Features](https://marmelab.com/react-admin/Features.html) documentation page to discover them all.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
React Admin already includes 230+ hooks and components. And it always allow you to make your own, thanks to the building blocks it provides. Feel free to read through its [All Features](https://marmelab.com/react-admin/Features.html) documentation page to discover them all.
React Admin already includes 230+ hooks and components. And it always allows you to make your own, thanks to the building blocks it provides. Feel free to read through its [All Features](https://marmelab.com/react-admin/Features.html) documentation page to discover them all.

Comment on lines +255 to +257
We can improve the UX further by rendering an [`<AutocompleteInput>`](https://marmelab.com/react-admin/AutocompleteInput.html) instead.

`<AutocompleteInput>` allows to search for a related record by typing its name in an input field. This is much more convenient when there are many records to choose from.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a lot of tip for replacing the <InputGuesser> by an <AutocompleteInput>. I think API Platform Admin should provide a prop to do this instead.

@@ -9,9 +9,9 @@ the admin will fetch the relations one by one.

In this case, it can be improved by doing only one request for all the related resources instead.

To do so, you need to make sure the [search filter](../core/filters.md#search-filter) is enabled for the identifier of the related resource.
To do so, you need to make sure the [search filter](../core/filters.md#apifilter-attribute) is enabled for the identifier of the related resource.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
To do so, you need to make sure the [search filter](../core/filters.md#apifilter-attribute) is enabled for the identifier of the related resource.
To do so, you need to make sure the [search filter](../core/doctrine-filters.md#search-filter) is enabled for the identifier of the related resource.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants