Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
59687a2
fix: remove legacy doctrine php 8 attribute note (#1477)
solverat Nov 24, 2021
d0ba811
feat(admin): add Mercure documentation (#1479)
alanpoulain Nov 29, 2021
7f3b6a0
feat: extract Mercure hub from response headers (#1480)
alanpoulain Nov 30, 2021
5067329
docs: Some typo fixes (#1481)
Levure Dec 1, 2021
aaaebf3
fix: add missing enabled: true in doctrine filters (#1483)
Gu3 Dec 14, 2021
0c6ff90
fix: wrong type passed to `assertResponseStatusCodeSame` (#1485)
GregoireHebert Dec 15, 2021
648990a
docs: update authentication-support.md (#1484)
4c0n Dec 15, 2021
43b39f6
fix: Mercure env vars (#1487)
dunglas Dec 16, 2021
0237d8d
fix: [doc] Use the Mailer component instead of SwiftMailer (#1488)
mdoutreluingne Dec 20, 2021
80b93d0
fix(fosrest): wrong internal links (#1494)
COil Jan 16, 2022
9372215
fix(doc): path to EventPriorities.php (#1496)
lobodol Jan 24, 2022
13c8c2a
chore: upgrade super linter (#1500)
alanpoulain Jan 31, 2022
45dc2b8
docs: fix broken link kubernetes.md (#1499)
Lenny4 Jan 31, 2022
da83f0c
fix(admin): make sure code is working in TS (#1501)
alanpoulain Feb 3, 2022
ae7ae1a
fix: remove extra bracket (#1504)
AbdelilahJabri Feb 10, 2022
1d40133
fix: yaml example code of "Calculated Field" (#1506)
ttskch Feb 21, 2022
b7a111e
Update serialization.md (#1508)
Mathieu33260 Feb 24, 2022
b15e01e
docs: add note on using PUT method to upload files (#1509)
alcalyn Feb 24, 2022
e886bb2
fix: wrong closing bracket (#1515)
Mar 11, 2022
f938287
fix: link in controllers.md (#1516)
Zebradil Mar 12, 2022
d4f9e38
Bumped up xdebug version to support php 8.1 (#1514)
mchojrin Mar 13, 2022
378a37f
fix: [doc] Update URL to point to the existing page, change `main` to…
maks-rafalko Mar 13, 2022
f1aea51
docs(dataprovider): Use argument binding instead of decoration (#1456)
danieleambrosino Mar 13, 2022
0bc822a
docs: update php type and replace annotations with PHP attributes (#1…
StephaneBullier Mar 13, 2022
dfc88c1
docs: Add information about how to significantly improve the test sui…
maks-rafalko Mar 13, 2022
5bbb16e
docs(security): update ApiProperty variables (#1351)
xavren Mar 13, 2022
032b914
Merge branch 2.6 into main
soyuka Mar 14, 2022
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
9 changes: 9 additions & 0 deletions .github/linters/.textlintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"rules": {
"terminology": {
"exclude": [
"Node(?:js)?"
]
}
}
}
82 changes: 52 additions & 30 deletions admin/authentication-support.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,22 @@ API Platform Admin delegates the authentication support to React Admin.
Refer to [the chapter dedicated to authentication in the React Admin documentation](https://marmelab.com/react-admin/Authentication.html)
for more information.

In short, you have to tweak data provider and api documentation parser, like this:
In short, you have to tweak the data provider and the API documentation parser like this:

```javascript
// admin/src/App.js
```typescript
// pwa/pages/admin/index.tsx

import React from "react";
import Head from "next/head";
import { Redirect, Route } from "react-router-dom";
import { HydraAdmin, hydraDataProvider as baseHydraDataProvider, fetchHydra as baseFetchHydra, useIntrospection } from "@api-platform/admin";
import parseHydraDocumentation from "@api-platform/api-doc-parser/lib/hydra/parseHydraDocumentation";
import authProvider from "./authProvider";
import {
fetchHydra as baseFetchHydra,
hydraDataProvider as baseHydraDataProvider,
useIntrospection,
} from "@api-platform/admin";
import { parseHydraDocumentation } from "@api-platform/api-doc-parser";
import authProvider from "utils/authProvider";
import { ENTRYPOINT } from "config/entrypoint";

const entrypoint = process.env.REACT_APP_API_ENTRYPOINT;
const getHeaders = () => localStorage.getItem("token") ? {
Authorization: `Bearer ${localStorage.getItem("token")}`,
} : {};
Expand All @@ -33,35 +37,53 @@ const RedirectToLogin = () => {
}
return <Redirect to="/login" />;
};
const apiDocumentationParser = async (entrypoint) => {
const apiDocumentationParser = async () => {
try {
const { api } = await parseHydraDocumentation(entrypoint, { headers: getHeaders });
return { api };
return await parseHydraDocumentation(ENTRYPOINT, { headers: getHeaders });
} catch (result) {
if (result.status === 401) {
// Prevent infinite loop if the token is expired
localStorage.removeItem("token");

return {
api: result.api,
customRoutes: [
<Route path="/" component={RedirectToLogin} />
],
};
const { api, response, status } = result;
if (status !== 401 || !response) {
throw result;
}

throw result;
// Prevent infinite loop if the token is expired
localStorage.removeItem("token");

return {
api,
response,
status,
customRoutes: [
<Route key="/" path="/" component={RedirectToLogin} />
],
};
}
};
const dataProvider = baseHydraDataProvider(entrypoint, fetchHydra, apiDocumentationParser);
const dataProvider = baseHydraDataProvider({
entrypoint: ENTRYPOINT,
httpClient: fetchHydra,
apiDocumentationParser,
});

const AdminLoader = () => {
if (typeof window !== "undefined") {
const { HydraAdmin } = require("@api-platform/admin");
return <HydraAdmin dataProvider={dataProvider} authProvider={authProvider} entrypoint={window.origin} />;
}

return <></>;
};

const Admin = () => (
<>
<Head>
<title>API Platform Admin</title>
</Head>

export default () => (
<HydraAdmin
dataProvider={ dataProvider }
authProvider={ authProvider }
entrypoint={ entrypoint }
/>
<AdminLoader />
</>
);
export default Admin;
```

For the implementation of the auth provider, you can find a working example in the [API Platform's demo application](https://github.com/api-platform/demo/blob/master/admin/src/authProvider.js).
For the implementation of the auth provider, you can find a working example in the [API Platform's demo application](https://github.com/api-platform/demo/blob/main/pwa/utils/authProvider.tsx).
65 changes: 38 additions & 27 deletions admin/components.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@

### AdminGuesser

`<AdminGuesser>` renders automatically an [<Admin> component](https://marmelab.com/react-admin/Admin.html) for resources exposed by a web API documented with any format supported by `@api-platform/api-doc-parser` (for Hydra documented APIs,
use the [<HydraAdmin> component](components.md#hydraadmin) instead).
It also creates a [schema analyzer](components.md#schemaanalyzer) context, where the `schemaAnalyzer` service (for getting information about the provided API documentation) is stored.
`<AdminGuesser>` renders automatically an [Admin component](https://marmelab.com/react-admin/Admin.html) for resources exposed by a web API documented with any format supported by `@api-platform/api-doc-parser` (for Hydra documented APIs,
use the [HydraAdmin component](components.md#hydraadmin) instead).
It also creates a [schema analyzer](components.md#schema-analyzer) context, where the `schemaAnalyzer` service (for getting information about the provided API documentation) is stored.

`<AdminGuesser>` renders all exposed resources by default, but you can choose what resource you want to render by passing [<ResourceGuesser> components](components.md#resourceguesser) as children.
`<AdminGuesser>` renders all exposed resources by default, but you can choose what resource you want to render by passing [ResourceGuesser components](components.md#resourceguesser) as children.
Deprecated resources are hidden by default, but you can add them back using an explicit `<ResourceGuesser>` component.

```javascript
Expand All @@ -21,12 +21,12 @@ const App = () => (
dataProvider={dataProvider}
authProvider={authProvider}>
<ResourceGuesser
name"books"
name="books"
list={BooksList}
show={BooksShow}
edit={BooksEdit}
create={BooksCreate} />
<ResourceGuesser name"authors" />
<ResourceGuesser name="authors" />
</AdminGuesser>
)

Expand All @@ -45,7 +45,8 @@ export default App;

### ResourceGuesser

Based on React Admin [<Resource> component](https://marmelab.com/react-admin/Resource.html), `ResourceGuesser` provides default props [<CreateGuesser>](components.md#createguesser), [<ListGuesser>](components.md#listguesser), [<EditGuesser>](components.md#editguesser) and [<ShowGuesser>](components.md#showguesser).
Based on React Admin [Resource component](https://marmelab.com/react-admin/Resource.html), `<ResourceGuesser>` provides default props [CreateGuesser](components.md#createguesser), [ListGuesser](components.md#listguesser), [EditGuesser](components.md#editguesser) and [ShowGuesser](components.md#showguesser).

Otherwise, you can pass it your own CRUD components using `create`, `list`, `edit`, `show` props.

```javascript
Expand Down Expand Up @@ -77,18 +78,18 @@ export default App;
|------|--------|-------|----------|--------------------------|
| name | string | - | yes | endpoint of the resource |

You can also use props accepted by React Admin [<Resource> component](https://marmelab.com/react-admin/Resource.html). For example, the props `list`, `show`, `create` or `edit`.
You can also use props accepted by React Admin [Resource component](https://marmelab.com/react-admin/Resource.html). For example, the props `list`, `show`, `create` or `edit`.

## Page Components

### ListGuesser

Based on React Admin [<List>](https://marmelab.com/react-admin/List.html), ListGuesser displays a list of resources in a [<Datagrid>](https://marmelab.com/react-admin/List.html#the-datagrid-component), according to children passed to it (usually [<FieldGuesser>](components.md#fieldguesser) or any [field component](https://marmelab.com/react-admin/Fields.html#basic-fields)
Based on React Admin [List](https://marmelab.com/react-admin/List.html), `<ListGuesser>` displays a list of resources in a [Datagrid](https://marmelab.com/react-admin/List.html#the-datagrid-component), according to children passed to it (usually [FieldGuesser](components.md#fieldguesser) or any [field component](https://marmelab.com/react-admin/Fields.html#basic-fields)
available in React Admin).

Use `hasShow` and `hasEdit` props if you want to display `show` and `edit` buttons (both set to `true` by default).

By default, `<ListGuesser>` comes with [<Pagination>](components.md#pagination).
By default, `<ListGuesser>` comes with [Pagination](components.md#pagination).

```javascript
// BooksList.js
Expand All @@ -114,12 +115,12 @@ export const BooksList = props => (
| resource | string | - | yes | endpoint of the resource |
| filters | element | - | no | filters that can be applied to the list |

You can also use props accepted by React Admin [<List>](https://marmelab.com/react-admin/List.html).
You can also use props accepted by React Admin [List](https://marmelab.com/react-admin/List.html).

### CreateGuesser

Displays a creation page for a single item. Uses React Admin [<Create>](https://marmelab.com/react-admin/CreateEdit.html) and [<SimpleForm>](https://marmelab.com/react-admin/CreateEdit.html#the-simpleform-component) components.
For simple inputs, you can pass as children API Platform Admin [<InputGuesser>](components.md#inputguesser), or any React Admin [Input components](https://marmelab.com/react-admin/Inputs.html#input-components) for more complex inputs.
Displays a creation page for a single item. Uses React Admin [Create](https://marmelab.com/react-admin/CreateEdit.html) and [SimpleForm](https://marmelab.com/react-admin/CreateEdit.html#the-simpleform-component) components.
For simple inputs, you can pass as children API Platform Admin [InputGuesser](components.md#inputguesser), or any React Admin [Input components](https://marmelab.com/react-admin/Inputs.html#input-components) for more complex inputs.

```javascript
// BooksCreate.js
Expand All @@ -143,12 +144,12 @@ export const BooksCreate = props => (
| children | node or function | - | no | - |
| resource | string | - | yes | endpoint of the resource |

You can also use props accepted by React Admin [<Create>](https://marmelab.com/react-admin/CreateEdit.html).
You can also use props accepted by React Admin [Create](https://marmelab.com/react-admin/CreateEdit.html).

### EditGuesser

Displays an edition page for a single item. Uses React Admin [<Edit>](https://marmelab.com/react-admin/CreateEdit.html) and [<SimpleForm>](https://marmelab.com/react-admin/CreateEdit.html#the-simpleform-component) components.
For simple inputs, you can use API Platform Admin [<InputGuesser>](components.md#inputguesser), or any React Admin [Input components](https://marmelab.com/react-admin/Inputs.html#input-components) for more complex inputs.
Displays an edition page for a single item. Uses React Admin [Edit](https://marmelab.com/react-admin/CreateEdit.html) and [SimpleForm](https://marmelab.com/react-admin/CreateEdit.html#the-simpleform-component) components.
For simple inputs, you can use API Platform Admin [InputGuesser](components.md#inputguesser), or any React Admin [Input components](https://marmelab.com/react-admin/Inputs.html#input-components) for more complex inputs.

```javascript
// BooksEdit.js
Expand All @@ -172,11 +173,11 @@ export const BooksEdit = props => (
| children | node or function | - | no | - |
| resource | string | - | yes | endpoint of the resource |

You can also use props accepted by React Admin [<Edit>](https://marmelab.com/react-admin/CreateEdit.html).
You can also use props accepted by React Admin [Edit](https://marmelab.com/react-admin/CreateEdit.html).

### ShowGuesser

Displays a detailed page for one item. Based on React Admin [<Show> component](https://marmelab.com/react-admin/Show.html). You can pass [<FieldGuesser>](components.md#fieldguesser) as children for simple fields, or use any of React Admin [basic fields](https://marmelab.com/react-admin/Fields.html#basic-fields) for more complex fields.
Displays a detailed page for one item. Based on React Admin [Show component](https://marmelab.com/react-admin/Show.html). You can pass [FieldGuesser](components.md#fieldguesser) as children for simple fields, or use any of React Admin [basic fields](https://marmelab.com/react-admin/Fields.html#basic-fields) for more complex fields.

```javascript
// BooksShow.js
Expand All @@ -200,13 +201,14 @@ export const BooksShow = props => (
| children | node or function | - | no | - |
| resource | string | - | yes | endpoint of the resource |

You can also use props accepted by React Admin [<Show> component](https://marmelab.com/react-admin/Show.html).
You can also use props accepted by React Admin [Show component](https://marmelab.com/react-admin/Show.html).

## Hydra

### HydraAdmin

Creates a complete Admin, as [`<AdminGuesser>`](components.md#adminguesser), but configured specially for [Hydra](https://www.hydra-cg.com/). If you want to use other formats (see supported formats: `@api-platform/api-doc-parser`) use [<AdminGuesser>](components.md#adminguesser) instead.
Creates a complete Admin, as [AdminGuesser](components.md#adminguesser), but configured specially for [Hydra](https://www.hydra-cg.com/).
If you want to use other formats (see supported formats: `@api-platform/api-doc-parser`) use [AdminGuesser](components.md#adminguesser) instead.

```javascript
// App.js
Expand All @@ -228,13 +230,20 @@ export default App;

#### HydraAdmin Props

| Name | Type | Value | required | Description |
|------------|--------|-------|----------|-----------------------|
| entrypoint | string | - | yes | entrypoint of the API |
| Name | Type | Value | required | Description |
|------------|----------------|-------|----------|------------------------------|
| entrypoint | string | - | yes | entrypoint of the API |
| mercure | boolean|object | * | yes | configuration to use Mercure |

\* `false` to explicitly disable, `true` to enable with default parameters or an object with the following properties:
- `hub`: the URL to your Mercure hub
- `jwt`: a subscriber JWT to access your Mercure hub
- `topicUrl`: the topic URL of your resources

### Data Provider

Based on React Admin `create`, `delete`, `getList`, `getManyReference`, `getOne`, `update` methods, the `dataProvider` is used by API Platform Admin to communicate with the API. In addition, the specific `introspect` method parses your API documentation.
Based on React Admin `create`, `delete`, `getList`, `getManyReference`, `getOne`, `update` methods, the `dataProvider` is used by API Platform Admin to communicate with the API.
In addition, the specific `introspect` method parses your API documentation.
Note that the `dataProvider` can be overridden to fit your API needs.

### Schema Analyzer
Expand All @@ -245,13 +254,15 @@ Analyses your resources and retrieves their types according to the [Schema.org](

### Pagination

Set by default in the [<ListGuesser> component](components.md#listguesser), the `Pagination` component uses React Admin [<Pagination> component](https://marmelab.com/react-admin/List.html#pagination).
By default, it renders 30 items per page and displays a navigation UI. If you want to change the number of items per page or disable the pagination, see the [Pagination documentation](../core/pagination.md).
Set by default in the [ListGuesser component](components.md#listguesser), the `Pagination` component uses React Admin [Pagination component](https://marmelab.com/react-admin/List.html#pagination).
By default, it renders 30 items per page and displays a navigation UI.
If you want to change the number of items per page or disable the pagination, see the [Pagination documentation](../core/pagination.md).
It is also capable to handle partial pagination.

### FieldGuesser

Renders fields according to their types, using the [schema analyzer](components.md#schemaanalyzer). Based on React Admin [field components](https://marmelab.com/react-admin/Fields.html).
Renders fields according to their types, using the [schema analyzer](components.md#schemaanalyzer).
Based on React Admin [field components](https://marmelab.com/react-admin/Fields.html).

```javascript
// BooksShow.js
Expand Down
11 changes: 3 additions & 8 deletions admin/customizing.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@ To do so, you can use the React components provided by API Platform Admin itself

## Customizing the Admin's Main Page and the Resource List

By default, API Platform Admin automatically builds a tailored [`<Resource>` component](https://marmelab.com/react-admin/Resource.html) (and all its appropriate children) for each resource type exposed by a web API.
By default, API Platform Admin automatically builds a tailored [Resource component](https://marmelab.com/react-admin/Resource.html) (and all its appropriate children) for each resource type exposed by a web API.
Under the hood it uses the `@api-platform/api-doc-parser` library to parse the API documentation. The API documentation can use Hydra, OpenAPI and any other format supported by the library.
Resources are listed in the order they appear in the machine-readable documentation.

However, it's also possible to display only specific resources, and to order them, while still benefiting from all discovery features provided by API Platform Admin.
To cherry-pick the resources to make available through the admin, pass a list of `<ResourceGuesser>` components as children of the root component:

```javascript
import React from "react";
import { HydraAdmin, ResourceGuesser } from "@api-platform/admin";

export default () => (
Expand All @@ -28,14 +27,13 @@ export default () => (
);
```

Instead of using the `<ResourceGuesser>` component provided by API Platform Admin, you can also pass custom React Admin's [`<Resource>` components](https://marmelab.com/react-admin/Resource.html), or any other React components that are supported by React Admin's [`<Admin>`](https://marmelab.com/react-admin/Admin.html).
Instead of using the `<ResourceGuesser>` component provided by API Platform Admin, you can also pass custom React Admin's [Resource components](https://marmelab.com/react-admin/Resource.html), or any other React components that are supported by React Admin's [Admin](https://marmelab.com/react-admin/Admin.html).

## Customizing the List View

The list view can be customized following the same pattern:

```javascript
import React from "react";
import {
HydraAdmin,
ResourceGuesser,
Expand Down Expand Up @@ -70,7 +68,6 @@ In addition to the `<FieldGuesser>` component, [all React Admin Fields component
For the show view:

```javascript
import React from "react";
import {
HydraAdmin,
ResourceGuesser,
Expand Down Expand Up @@ -107,7 +104,6 @@ In addition to the `<FieldGuesser>` component, [all React Admin Fields component
Again, the same logic applies to forms. Here is how to customize the create form:

```javascript
import React from "react";
import {
HydraAdmin,
ResourceGuesser,
Expand Down Expand Up @@ -146,7 +142,6 @@ For instance, using an autocomplete input is straightforward, [check out the ded
Finally, you can customize the edit form the same way:

```javascript
import React from "react";
import {
HydraAdmin,
ResourceGuesser,
Expand Down Expand Up @@ -183,6 +178,6 @@ For instance, using an autocomplete input is straightforward, [checkout the dedi
## Going Further

API Platform is built on top of [React Admin](https://marmelab.com/react-admin/).
You can use all the features provided by the underlying library with API Platform Admin, including support for [file upload](https://marmelab.com/react-admin/DataProviders.html#decorating-your-data-provider-example-of-file-upload), [authentication](https://marmelab.com/react-admin/Authentication.html), [authorization](https://marmelab.com/react-admin/Authorization.html) and deeper customization.
You can use all the features provided by the underlying library with API Platform Admin, including support for [authentication](https://marmelab.com/react-admin/Authentication.html), [authorization](https://marmelab.com/react-admin/Authorization.html) and deeper customization.

To learn more about these capabilities, refer to [the React Admin documentation](https://marmelab.com/react-admin/).
1 change: 0 additions & 1 deletion admin/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ To initialize API Platform Admin, register it in your application.
For instance, if you used Create React App, replace the content of `src/App.js` by:

```javascript
import React from "react";
import { HydraAdmin } from "@api-platform/admin";

// Replace with your own API entrypoint
Expand Down
Loading