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

[Doc] Improve the Show section #9423

Merged
merged 5 commits into from
Nov 7, 2023
Merged
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
366 changes: 229 additions & 137 deletions docs/Show.md

Large diffs are not rendered by default.

124 changes: 106 additions & 18 deletions docs/ShowBase.md
Original file line number Diff line number Diff line change
@@ -5,20 +5,19 @@ title: "The ShowBase Component"

# `<ShowBase>`

The `<ShowBase>` component handles the headless logic of the Show page:
`<ShowBase>` is a headless component that lets you build custom Show pages. It handles the logic of the Show page:

- it calls `useShowController` to fetch the record from the data provider via `dataProvider.getOne()`,
- it computes the default page title
- it creates a `ShowContext` and a `RecordContext`,
- it renders its child component

Contrary to `<Show>`, it does not render the page layout, so no title, no actions, and no `<Card>`.
Contrary to [`<Show>`](./Show.md), it does not render the page layout, so no title, no actions, and no `<Card>`.

## Usage

Use `<ShowBase>` instead of `<Show>` when you want a completely custom page layout, without the default actions and title.

{% raw %}
```jsx
// in src/posts.jsx
import * as React from "react";
@@ -41,28 +40,115 @@ const PostShow = () => (
</div>
</ShowBase>
);
```

Components using `<ShowBase>` can be used as the `show` prop of a `<Resource>` component:

```jsx
// in src/App.jsx
import * as React from "react";
import { Admin, Resource } from 'react-admin';
import jsonServerProvider from 'ra-data-json-server';

import { dataProvider } from './dataProvider';
import { PostShow } from './posts';

const App = () => (
<Admin dataProvider={jsonServerProvider('https://jsonplaceholder.typicode.com')}>
<Admin dataProvider={dataProvider}>
<Resource name="posts" show={PostShow} />
</Admin>
);
```
{% endraw %}

**Tip**: See [`useShowController`](./useShowController.md) for a completely headless version of this component.

## Props

* `children` the components that actually render something
* [`queryOptions`](#client-query-options): options to pass to the react-query client
| Prop | Required | Type | Default | Description
|------------------|----------|-------------------|---------|--------------------------------------------------------
| `children` | Required | `ReactNode` | | The components rendering the record fields
| `disable Authentication` | Optional | `boolean` | | Set to `true` to disable the authentication check
| `empty WhileLoading` | Optional | `boolean` | | Set to `true` to return `null` while the list is loading
| `id` | Optional | `string` | | The record identifier. If not provided, it will be deduced from the URL
| `queryOptions` | Optional | `object` | | The options to pass to the `useQuery` hook
| `resource` | Optional | `string` | | The resource name, e.g. `posts`

## `children`

`<ShowBase>` renders its children wrapped by a `RecordContext`, so you can use any component that depends on such a context to be defined - including all [Field components](./Fields.md).

For instance, to display several fields in a single line, you can use Material UI’s `<Grid>` component:

{% raw %}
```jsx
import { ShowBase, TextField, DateField, ReferenceField, WithRecord } from 'react-admin';
import { Grid } from '@mui/material';
import StarIcon from '@mui/icons-material/Star';

const BookShow = () => (
<ShowBase emptyWhileLoading>
<Grid container spacing={2} sx={{ margin: 2 }}>
<Grid item xs={12} sm={6}>
<TextField label="Title" source="title" />
</Grid>
<Grid item xs={12} sm={6}>
<ReferenceField label="Author" source="author_id" reference="authors">
<TextField source="name" />
</ReferenceField>
</Grid>
<Grid item xs={12} sm={6}>
<DateField label="Publication Date" source="published_at" />
</Grid>
<Grid item xs={12} sm={6}>
<WithRecord label="Rating" render={record => <>
{[...Array(record.rating)].map((_, index) => <StarIcon key={index} />)}
</>} />
</Grid>
</Grid>
</ShowBase>
);
```
{% endraw %}

## `disableAuthentication`

## Client Query Options
By default, the `<ShowBase>` component will automatically redirect the user to the login page if the user is not authenticated. If you want to disable this behavior and allow anonymous access to a show page, set the `disableAuthentication` prop to `true`.

```jsx
const PostShow = () => (
<ShowBase disableAuthentication>
...
</ShowBase>
);
```

## `emptyWhileLoading`

By default, `<ShowBase>` renders its child component even before the `dataProvider.getOne()` call returns. If you use `<SimpleShowLayout>` or `<TabbedShowLayout>`, this isn't a problem as these components only render when the record has been fetched. But if you use a custom child component that expects the record context to be defined, your component will throw an error.

The `<ShowBase emptyWhileLoading>` prop provides a convenient shortcut for that use case. When enabled, `<ShowBase>` won't render its child until the record is loaded.

```jsx
const BookShow = () => (
<ShowBase emptyWhileLoading>
...
</ShowBase>
);
```

## `id`

By default, `<ShowBase>` deduces the identifier of the record to show from the URL path. So under the `/posts/123/show` path, the `id` prop will be `123`. You may want to force a different identifier. In this case, pass a custom `id` prop.

```jsx
export const PostShow = () => (
<ShowBase id="123">
...
</ShowBase>
);
```

**Tip**: Pass both a custom `id` and a custom `resource` prop to use `<ShowBase>` independently of the current URL. This even allows you to use more than one `<ShowBase>` component in the same page.

## `queryOptions`

`<ShowBase>` accepts a `queryOptions` prop to pass options to the react-query client.

@@ -107,14 +193,16 @@ The default `onError` function is:
}
```

## See Also

* [`useShowController`](./useShowController.md) for a completely headless version of this component
## `resource`

## API
By default, `<ShowBase>` operates on the current `ResourceContext` (defined at the routing level), so under the `/posts/1/show` path, the `resource` prop will be `posts`. You may want to force a different resource. In this case, pass a custom `resource` prop, and it will override the `ResourceContext` value.

* [`<ShowBase>`]
* [`<Show>`]
```jsx
export const UsersShow = () => (
<ShowBase resource="users">
...
</ShowBase>
);
```

[`<ShowBase>`]: https://github.com/marmelab/react-admin/blob/master/packages/ra-core/src/controller/show/ShowBase.tsx
[`<Show>`]: https://github.com/marmelab/react-admin/blob/master/packages/ra-ui-materialui/src/detail/Show.tsx
**Tip**: Pass both a custom `id` and a custom `resource` prop to use `<ShowBase>` independently of the current URL. This even allows you to use more than one `<ShowBase>` component in the same page.
8 changes: 1 addition & 7 deletions docs/ShowGuesser.md
Original file line number Diff line number Diff line change
@@ -36,10 +36,4 @@ React-admin provides guessers for the `List` view ([`<ListGuesser>`](./ListGuess

## See Also

* [API Platform Admin](https://api-platform.com/docs/admin/) has a much more powerful `<ShowGuesser>` component that takes advantage of the API Schema.

## API

* [`<ShowGuesser>`]

[`<ShowGuesser>`]: https://github.com/marmelab/react-admin/blob/master/packages/ra-ui-materialui/src/detail/ShowGuesser.tsx
* [API Platform Admin](https://api-platform.com/docs/admin/) has a much more powerful `<ShowGuesser>` component that takes advantage of the API Schema.
Loading