Skip to content

Commit c73103f

Browse files
committed
Merge branch '2.3'
2 parents 2ea3fb2 + 1138e72 commit c73103f

21 files changed

+666
-361
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ script:
2121
- find . -name '*.md' ! -name 'conduct.md' ! -name 'heroku.md' -exec proselint {} \;
2222
- cd $TRAVIS_BUILD_DIR/../website
2323
- bin/generate-nav
24-
- yarn gatsby build
24+
- GATSBY_BRANCH_NAME=$TRAVIS_BRANCH yarn gatsby build
2525
# Preserve artifacts
2626
- cd $TRAVIS_BUILD_DIR
2727
- mv ../website/public public

admin/authentication-support.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ const fetchHydra = (url, options = {}) => baseFetchHydra(url, {
7070
...options,
7171
headers: new Headers(fetchHeaders),
7272
});
73-
const hydraClient = api => hydraClient(api, fetchHydra);
73+
const dataProvider = api => hydraClient(api, fetchHydra);
7474
const apiDocumentationParser = entrypoint => parseHydraDocumentation(entrypoint, { headers: new Headers(fetchHeaders) })
7575
.then(
7676
({ api }) => ({ api }),
@@ -98,7 +98,7 @@ export default props => (
9898
apiDocumentationParser={apiDocumentationParser}
9999
authProvider={authProvider}
100100
entrypoint={entrypoint}
101-
dataProvider={hydraClient}
101+
dataProvider={dataProvider}
102102
/>
103103
);
104104
```

admin/getting-started.md

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ const myApiDocumentationParser = entrypoint => parseHydraDocumentation(entrypoin
9191
addField: true,
9292
addLabel: true
9393
};
94-
94+
9595
return { api };
9696
})
9797
;
@@ -126,7 +126,7 @@ const myApiDocumentationParser = entrypoint => parseHydraDocumentation(entrypoin
126126
.then( ({ api }) => {
127127
128128
const books = api.resources.find(({ name }) => 'books' === name);
129-
const description = books.fields.find(f => 'description' === f.name);
129+
const description = books.fields.find(({ name }) => 'description' === name);
130130
131131
description.input = props => (
132132
<RichTextInput {...props} source="description" />
@@ -194,37 +194,37 @@ __Note__: In this example, we choose to send the file via a multi-part form data
194194

195195
### Using a Custom Validation Function or Inject Custom Props
196196

197-
You can use `fieldProps` and `inputProps` to respectively inject custom properties to fields and inputs generated by API
198-
Platform Admin. This is particularly useful to add custom validation rules:
197+
Example to add a minLength validator on the `description` field:
199198

200199
```javascript
201200
import React, { Component } from 'react';
202-
import { AdminBuilder, hydraClient } from 'api-platform-admin';
203-
import parseHydraDocumentation from 'api-doc-parser/lib/hydra/parseHydraDocumentation';
201+
import { minLength } from 'react-admin';
202+
import RichTextInput from 'ra-input-rich-text';
203+
import { AdminBuilder, hydraClient } from '@api-platform-admin';
204+
import parseHydraDocumentation from '@api-platform/api-doc-parser/lib/hydra/parseHydraDocumentation';
204205

205206
const entrypoint = 'https://demo.api-platform.com';
206207

207208
export default class extends Component {
208-
state = {api: null};
209+
state = { api: null };
209210

210211
componentDidMount() {
211-
parseHydraDocumentation(entrypoint).then( ({ api }) => => {
212-
const books = api.resources.find(r => 'books' === r.name);
212+
parseHydraDocumentation(entrypoint).then(({ api }) => {
213+
const books = api.resources.find(({ name }) => 'books' === name);
213214

214-
books.writableFields.find(f => 'description' === f.name).inputProps = {
215-
validate: value => value.length >= 30 ? undefined : 'Minimum length: 30';
216-
};
215+
const description = books.fields.find(({ name }) => 'description' === name)
216+
description.input = props => (
217+
<RichTextInput source={description.name} label="Description" validate={minLength(30)} {...props} />
218+
)
217219

218-
this.setState({api: api});
219-
220-
return { api };
220+
this.setState({ api });
221221
});
222222
}
223223

224224
render() {
225225
if (null === this.state.api) return <div>Loading...</div>;
226226

227-
return <AdminBuilder api={this.state.api} dataProvider={hydraClient(entrypoint)}/>
227+
return <AdminBuilder api={ this.state.api } dataProvider={ hydraClient(this.state.api) }/>
228228
}
229229
}
230230
```

admin/handling-relations-to-collections.md

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,9 @@
11
# Handling Relations to Collections
22

3-
Currently, API Platform Admin doesn't handle `to-many` relations. The core library [is being patched](https://github.com/api-platform/core/pull/1189)
4-
to document relations to collections through OWL.
5-
6-
Meanwhile, it is possible to manually configure API Platform to handle relations to collections.
7-
8-
We will create the admin for an API exposing `Person` and `Book` resources linked with a `many-to-many`
3+
Considering an API exposing `Person` and `Book` resources linked with a `many-to-many`
94
relation between them (through the `authors` property).
105

11-
This API can be created using the following PHP code:
6+
This API using the following PHP code:
127

138
```php
149
<?php
@@ -74,54 +69,59 @@ class Book
7469
}
7570
```
7671

77-
Let's customize the components used for the `authors` property:
72+
The admin handles this `to-many` relation automatically!
73+
74+
But we can go further:
75+
76+
## Customizing a Property
77+
78+
Let's customize the components used for the `authors` property, to display them by their 'name' instead 'id' (the default behavior).
7879

7980
```javascript
8081
import React, { Component } from 'react';
8182
import { ReferenceArrayField, SingleFieldList, ChipField, ReferenceArrayInput, SelectArrayInput } from 'react-admin';
8283
import { AdminBuilder, hydraClient } from '@api-platform/admin';
83-
import parseHydraDocumentation from 'api-doc-parser/lib/hydra/parseHydraDocumentation';
84+
import parseHydraDocumentation from '@api-platform/api-doc-parser/lib/hydra/parseHydraDocumentation';
8485

8586
const entrypoint = 'https://demo.api-platform.com';
8687

8788
export default class extends Component {
88-
state = {api: null, resources: null};
89+
state = { api: null }
8990

9091
componentDidMount() {
91-
parseHydraDocumentation(entrypoint).then({api, resources} => {
92-
const books = r.find(r => 'books' === r.name);
92+
parseHydraDocumentation(entrypoint).then(({api}) => {
93+
const books = api.resources.find(({ name }) => 'books' === name)
94+
const authors = books.fields.find(({ name }) => 'authors' === name)
9395

9496
// Set the field in the list and the show views
95-
books.readableFields.find(f => 'authors' === f.name).fieldComponent =
96-
<ReferenceArrayField label="Authors" reference="people" source="authors" key="authors">
97+
authors.field = props => (
98+
<ReferenceArrayField source={authors.name} reference={authors.reference.name} key={authors.name} {...props}>
9799
<SingleFieldList>
98100
<ChipField source="name" key="name"/>
99101
</SingleFieldList>
100102
</ReferenceArrayField>
101-
;
103+
);
102104

103105
// Set the input in the edit and create views
104-
books.writableFields.find(f => 'authors' === f.name).inputComponent =
105-
<ReferenceArrayInput label="Authors" reference="people" source="authors" key="authors">
106+
authors.input = props => (
107+
<ReferenceArrayInput source={authors.name} reference={authors.reference.name} label="Authors" key={authors.name} {...props} allowEmpty>
106108
<SelectArrayInput optionText="name"/>
107109
</ReferenceArrayInput>
108-
;
110+
);
109111

110-
this.setState({api, resources});
112+
this.setState({ api });
111113
}
112114
)
113115
}
114116

115117
render() {
116118
if (null === this.state.api) return <div>Loading...</div>;
117119

118-
return <AdminBuilder api={this.state.api} dataProvider={hydraClient({entrypoint: entrypoint, resources: this.state.resources})}/>
120+
return <AdminBuilder api={ this.state.api } dataProvider={ hydraClient(this.state.api) }/>
119121
}
120122
}
121123
```
122124

123-
The admin now properly handles this `to-many` relation!
124-
125125
## Using an Autocomplete Input for Relations
126126

127127
We'll make one last improvement to our admin: transforming the relation selector we just created to use autocompletion.
@@ -161,11 +161,11 @@ Then edit the configuration of API Platform Admin to pass a `filterToQuery` prop
161161
// ...
162162

163163
// Set the input in the edit and create views
164-
books.writableFields.find(f => 'authors' === f.name).inputComponent =
165-
<ReferenceArrayInput label="Authors" reference="people" source="authors" key="authors" filterToQuery={searchText => ({ name: searchText })}>
166-
<SelectArrayInput optionText="name"/>
167-
</ReferenceArrayInput>
168-
;
164+
authors.input = props => (
165+
<ReferenceArrayInput source={authors.name} reference={authors.reference.name} label="Authors" key={authors.name} filterToQuery={searchText => ({ name: searchText })} {...props} allowEmpty>
166+
<SelectArrayInput optionText="name"/>
167+
</ReferenceArrayInput>
168+
);
169169

170170
// ...
171171
}

core/default-order.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ class Book
5757
}
5858
```
5959

60-
It's also possible to configure the default filter on an association property:
60+
It's also possible to configure the default order on an association property:
6161

6262
```php
6363
<?php

0 commit comments

Comments
 (0)