Skip to content

Commit ce9a890

Browse files
committed
Backport changes from 2.9.2 and 2.9.3
1 parent 18a4a12 commit ce9a890

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+875
-185
lines changed

.huskyrc

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"hooks": {
3+
"pre-commit": "lint-staged"
4+
}
5+
}

.lintstagedrc

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"*.{js,jsx,ts,tsx}": [
3+
"eslint --fix",
4+
"git add",
5+
],
6+
"*.{json,css,md}": [
7+
"prettier",
8+
"git add"
9+
]
10+
}

.prettierrc.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@ module.exports = {
1212
tabWidth: 4,
1313
trailingComma: 'es5',
1414
useTabs: false
15-
}
15+
}

CHANGELOG.md

+32
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,37 @@
11
# Changelog
22

3+
## v2.9.3
4+
5+
* Fix issue with `<TabbedForm>` when used inside a dialog ([3335](https://github.com/marmelab/react-admin/pull/3335)) ([griiettner](https://github.com/griiettner))
6+
* Fix `<AutoCompleteArrayInput>` not showing error message ([3327](https://github.com/marmelab/react-admin/pull/3327)) ([hithacker](https://github.com/hithacker))
7+
* Fix `<ListView>` component isn't exported ([3319](https://github.com/marmelab/react-admin/pull/3319)) ([cherniavskii](https://github.com/cherniavskii))
8+
* Fix `<MenuItemLink>` `primaryText` documentation ([3316](https://github.com/marmelab/react-admin/pull/3316)) ([fzaninotto](https://github.com/fzaninotto))
9+
* Fix typo in `callback` side effect documentation ([3297](https://github.com/marmelab/react-admin/pull/3297)) ([0xflotus](https://github.com/0xflotus))
10+
* Fix `<SelectInput>` is resettable even when it's disabled ([3293](https://github.com/marmelab/react-admin/pull/3293)) ([sagarbakhtar](https://github.com/sagarbakhtar))
11+
* Fix `<CheckboxGroupInput>` `options` documentation ([3292](https://github.com/marmelab/react-admin/pull/3292)) ([sagarbakhtar](https://github.com/sagarbakhtar))
12+
* Fix custom `<LogoutButton>` documentation ([3283](https://github.com/marmelab/react-admin/pull/3283)) ([sagarbakhtar](https://github.com/sagarbakhtar))
13+
* Fix posts list export in demo app ([3279](https://github.com/marmelab/react-admin/pull/3279)) ([fargito](https://github.com/fargito))
14+
* Fix nested property filter is hidden on location change but still applied ([3274](https://github.com/marmelab/react-admin/pull/3274)) ([donatascn](https://github.com/donatascn))
15+
* Fix duplicate API call in `<ReferenceArrayInput>` ([3252](https://github.com/marmelab/react-admin/pull/3252)) ([fargito](https://github.com/fargito))
16+
* Fix `<RichTextInput>` validation bugs ([3223](https://github.com/marmelab/react-admin/pull/3223)) ([cherniavskii](https://github.com/cherniavskii))
17+
* Fix `<AutocompleteInput>` popup re-renders after choice is selected ([3190](https://github.com/marmelab/react-admin/pull/3190)) ([FACOLOMBANI](https://github.com/FACOLOMBANI))
18+
* Replace tslint with eslint (because tslint is deprecated) ([3322](https://github.com/marmelab/react-admin/pull/3322)) ([djhi](https://github.com/djhi))
19+
* Update Prettier ([3304](https://github.com/marmelab/react-admin/pull/3304)) ([djhi](https://github.com/djhi))
20+
* Add `ra-auth-acl` to the ecosystem ([3301](https://github.com/marmelab/react-admin/pull/3301)) ([Kmaschta](https://github.com/Kmaschta))
21+
* Add pre-commit hooks to ensure code style is consistent on commits ([3306](https://github.com/marmelab/react-admin/pull/3306)) ([3334](https://github.com/marmelab/react-admin/pull/3334)) ([djhi](https://github.com/djhi))
22+
23+
## v2.9.2
24+
25+
* Fix spinner position in Login and Save buttons ([3276](https://github.com/marmelab/react-admin/pull/3276)) ([Luwangel](https://github.com/Luwangel))
26+
* Fix slow List view when fetching lots of rows ([3275](https://github.com/marmelab/react-admin/pull/3275)) ([slecoustre](https://github.com/slecoustre))
27+
* Fix `<BooleanInput>` does not show errors ([3271](https://github.com/marmelab/react-admin/pull/3271)) ([fargito](https://github.com/fargito))
28+
* Fix `<Query>` component sending request on every update ([3267](https://github.com/marmelab/react-admin/pull/3267)) ([fargito](https://github.com/fargito))
29+
* Fix duplicated entry in Reference documentation ([3259](https://github.com/marmelab/react-admin/pull/3259)) ([mabhub](https://github.com/mabhub))
30+
* Fix duplicated code formatting rules ([3258](https://github.com/marmelab/react-admin/pull/3258)) ([fargito](https://github.com/fargito))
31+
* Fix empty list after changing the items per page count ([3257](https://github.com/marmelab/react-admin/pull/3257)) ([sagarbakhtar](https://github.com/sagarbakhtar))
32+
* Fix `<RichTextInput>` does not use theme color to show focus ([3231](https://github.com/marmelab/react-admin/pull/3231)) ([cherniavskii](https://github.com/cherniavskii))
33+
* Add Bulgarian translation link ([3260](https://github.com/marmelab/react-admin/pull/3260)) ([ptodorov0](https://github.com/ptodorov0))
34+
335
## v2.9.1
436

537
* Fix handling of deleted references ([3216](https://github.com/marmelab/react-admin/pull/3216)) ([djhi](https://github.com/djhi))

Makefile

+2-1
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,8 @@ test-unit: ## launch unit tests
117117
fi
118118

119119
test-unit-watch: ## launch unit tests and watch for changes
120-
yarn -s test-unit --watch
120+
echo "Running unit tests..."; \
121+
yarn -s test-unit; \
121122

122123
test-e2e: ## launch end-to-end tests
123124
@if [ "$(build)" != "false" ]; then \

README.md

+5-1
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,9 @@ or
191191
yarn test
192192
```
193193

194-
When working on the end to end tests, you can leverage [cypress](https://www.cypress.io/) runner by starting the simple example yourself (`make run-simple`) and starting cypress in another terminal (`make test-e2e-local` or `yarn test-e2e-local`).
194+
Besides, tests related to the modified files are ran automatically at commit.
195+
196+
When working on the end to end tests, you can leverage [cypress](https://www.cypress.io/) runner by starting the simple example yourself (`make run-simple` or `yarn run-simple`) and starting cypress in another terminal (`make test-e2e-local` or `yarn test-e2e-local`).
195197

196198
If you have coding standards problems, you can fix them automatically using `prettier` by calling
197199

@@ -205,6 +207,8 @@ or
205207
yarn prettier
206208
```
207209

210+
However, these commands are ran automatically at each commit so you shouldn't have to worry about them.
211+
208212
If you want to contribute to the documentation, install [jekyll](https://jekyllrb.com/docs/home/), then call
209213

210214
```sh

cypress/.eslintrc

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
{
22
"extends": "../.eslintrc",
3-
"plugins": [
4-
"cypress"
5-
],
6-
"env": {
3+
"plugins": ["cypress"],
4+
"env": {
75
"cypress/globals": true
86
}
9-
}
7+
}

cypress/integration/create.js

+69
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,11 @@ describe('Create Page', () => {
7676
name: 'teaser',
7777
value: 'Test teaser',
7878
},
79+
{
80+
type: 'rich-text-input',
81+
name: 'body',
82+
value: 'Test body',
83+
},
7984
];
8085

8186
CreatePage.setValues(values);
@@ -103,6 +108,11 @@ describe('Create Page', () => {
103108
name: 'teaser',
104109
value: 'Test teaser',
105110
},
111+
{
112+
type: 'rich-text-input',
113+
name: 'body',
114+
value: 'Test body',
115+
},
106116
];
107117

108118
CreatePage.setValues(values);
@@ -124,6 +134,11 @@ describe('Create Page', () => {
124134
name: 'teaser',
125135
value: 'Test teaser',
126136
},
137+
{
138+
type: 'rich-text-input',
139+
name: 'body',
140+
value: 'Test body',
141+
},
127142
];
128143
CreatePage.setValues(values);
129144
CreatePage.submitAndAdd();
@@ -153,6 +168,11 @@ describe('Create Page', () => {
153168
name: 'commentable',
154169
value: false,
155170
},
171+
{
172+
type: 'rich-text-input',
173+
name: 'body',
174+
value: 'Test body',
175+
},
156176
];
157177

158178
CreatePage.setValues(values);
@@ -212,4 +232,53 @@ describe('Create Page', () => {
212232
expect(el).to.have.value('The real Slim Shady!')
213233
);
214234
});
235+
236+
it('should not show rich text input error message when field is untouched', () => {
237+
cy.get(CreatePage.elements.richTextInputError).should('not.exist');
238+
});
239+
240+
it('should show rich text input error message when form is submitted', () => {
241+
CreatePage.submit();
242+
cy.get(CreatePage.elements.richTextInputError)
243+
.should('exist')
244+
.contains('Required');
245+
});
246+
247+
it('should not show rich text input error message when form is submitted and input is filled with text', () => {
248+
CreatePage.submit();
249+
cy.get(CreatePage.elements.richTextInputError)
250+
.should('exist')
251+
.contains('Required');
252+
cy.get(CreatePage.elements.input('body', 'rich-text-input')).type(
253+
'text'
254+
);
255+
cy.get(CreatePage.elements.richTextInputError).should('not.exist');
256+
});
257+
258+
it('should show body in edit view after creating new post', () => {
259+
const values = [
260+
{
261+
type: 'input',
262+
name: 'title',
263+
value: 'Test title',
264+
},
265+
{
266+
type: 'textarea',
267+
name: 'teaser',
268+
value: 'Test teaser',
269+
},
270+
{
271+
type: 'rich-text-input',
272+
name: 'body',
273+
value: 'Test body',
274+
},
275+
];
276+
277+
CreatePage.setValues(values);
278+
CreatePage.submit();
279+
EditPage.gotoTab(2);
280+
cy.get(EditPage.elements.input('body', 'rich-text-input')).contains(
281+
'Test body'
282+
);
283+
});
215284
});

cypress/integration/edit.js

+8-7
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ describe('Edit Page', () => {
2525
});
2626

2727
it('should allow to update elements', () => {
28-
EditPostPage.setInputValue('title', 'Lorem Ipsum');
28+
EditPostPage.setInputValue('input', 'title', 'Lorem Ipsum');
2929
EditPostPage.submit();
3030
// Ensure react-admin has handled the update as it will redirect to the list page
3131
// once done
@@ -37,7 +37,7 @@ describe('Edit Page', () => {
3737
});
3838

3939
it('should redirect to list page after edit success', () => {
40-
EditPostPage.setInputValue('title', 'Lorem Ipsum +');
40+
EditPostPage.setInputValue('input', 'title', 'Lorem Ipsum +');
4141
EditPostPage.submit();
4242
cy.url().then(url => expect(url).to.contain('/#/posts'));
4343
});
@@ -71,13 +71,14 @@ describe('Edit Page', () => {
7171
);
7272

7373
// This validate that the current redux form values are not kept after we navigate
74-
EditCommentPage.setInputValue('body', 'Test');
74+
EditCommentPage.setInputValue('input', 'body', 'Test');
7575

7676
CreatePostPage.navigate();
7777

78-
cy.get(CreatePostPage.elements.bodyInput).should(el =>
79-
// When the Quill editor is empty, it add the "ql-blank" CSS class
80-
expect(el).to.have.class('ql-blank')
78+
cy.get(CreatePostPage.elements.input('body', 'rich-text-input')).should(
79+
el =>
80+
// When the Quill editor is empty, it add the "ql-blank" CSS class
81+
expect(el).to.have.class('ql-blank')
8182
);
8283
});
8384

@@ -116,7 +117,7 @@ describe('Edit Page', () => {
116117
);
117118

118119
// This validate that the current redux form values are not kept after we navigate
119-
EditPostPage.setInputValue('title', 'Another title');
120+
EditPostPage.setInputValue('input', 'title', 'Another title');
120121

121122
CreatePostPage.navigate();
122123
cy.get(CreatePostPage.elements.input('title')).should(el =>

cypress/integration/list.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ describe('List Page', () => {
218218
cy.get('#13-expand').should(el => expect(el).to.exist);
219219

220220
cy.get('[aria-label="Expand"]')
221-
.eq(0) // We still targets the first button labeled Expand because the previous one should now have a Close label
221+
.eq(0) // We still target the first button labeled Expand because the previous one should now have a Close label
222222
.click()
223223
.should(el => expect(el).to.have.attr('aria-expanded', 'true'))
224224
.should(el => expect(el).to.have.attr('aria-label', 'Close'));

cypress/support/CreatePage.js

+10-2
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,14 @@ export default url => ({
22
elements: {
33
addAuthor: '.button-add-authors',
44
body: 'body',
5-
bodyInput: '.ra-input-body .ql-editor',
6-
input: (name, type = 'input') => `.create-page ${type}[name='${name}']`,
5+
input: (name, type = 'input') => {
6+
if (type === 'rich-text-input') {
7+
return `.ra-input-${name} .ql-editor`;
8+
}
9+
return `.create-page ${type}[name='${name}']`;
10+
},
711
inputs: `.ra-input`,
12+
richTextInputError: '.create-page .ra-rich-text-input-error',
813
snackbar: 'div[role="alertdialog"]',
914
submitButton: ".create-page div[role='toolbar'] button[type='submit']",
1015
submitAndShowButton:
@@ -37,6 +42,9 @@ export default url => ({
3742
cy.get(this.elements.input(name, type)).clear();
3843
}
3944
cy.get(this.elements.input(name, type)).type(value);
45+
if (type === 'rich-text-input') {
46+
cy.wait(500);
47+
}
4048
},
4149

4250
setValues(values, clearPreviousValue = true) {

cypress/support/EditPage.js

+11-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@ export default url => ({
22
elements: {
33
body: 'body',
44
deleteButton: '.ra-delete-button',
5-
input: name => `.edit-page [name='${name}']`,
5+
input: (name, type = 'input') => {
6+
if (type === 'rich-text-input') {
7+
return `.ra-input-${name} .ql-editor`;
8+
}
9+
return `.edit-page [name='${name}']`;
10+
},
611
inputs: `.ra-input`,
712
tabs: `.form-tab`,
813
snackbar: 'div[role="alertdialog"]',
@@ -20,11 +25,14 @@ export default url => ({
2025
return cy.get(this.elements.title);
2126
},
2227

23-
setInputValue(name, value, clearPreviousValue = true) {
28+
setInputValue(type, name, value, clearPreviousValue = true) {
2429
if (clearPreviousValue) {
2530
cy.get(this.elements.input(name)).clear();
2631
}
27-
return cy.get(this.elements.input(name)).type(value);
32+
cy.get(this.elements.input(name)).type(value);
33+
if (type === 'rich-text-input') {
34+
cy.wait(500);
35+
}
2836
},
2937

3038
clickInput(name) {

docs/Actions.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ React-admin can handle the following side effects:
204204
- `redirectTo`: Redirect the user to another page. The property value should be the path to redirect the user to.
205205
- `refresh`: Force a rerender of the current view (equivalent to pressing the Refresh button). Set to true to enable.
206206
- `unselectAll`: Unselect all lines in the current datagrid. Set to true to enable.
207-
- `callback`: Execute an arbitrary function. The value should be the function to execute. React-admin will call the function with an object as parameter (`{ requestPayload, payload, error }`). The `payload` contains the decoded response body when it's successfull. When it's failed, the response body is passed in the `error`.
207+
- `callback`: Execute an arbitrary function. The value should be the function to execute. React-admin will call the function with an object as parameter (`{ requestPayload, payload, error }`). The `payload` contains the decoded response body when it's successful. When it's failed, the response body is passed in the `error`.
208208
- `basePath`: This is not a side effect, but it's used internally to compute redirection paths. Set it when you have a redirection side effect.
209209

210210
## Optimistic Rendering and Undo
@@ -565,7 +565,7 @@ The side effects accepted in the `meta` field of the action are the same as in t
565565
- `redirectTo`: Redirect the user to another page. The property value should be the path to redirect the user to.
566566
- `refresh`: Force a rerender of the current view (equivalent to pressing the Refresh button). Set to true to enable.
567567
- `unselectAll`: Unselect all lines in the current datagrid. Set to true to enable.
568-
- `callback`: Execute an arbitrary function. The value should be the function to execute. React-admin will call the function with an object as parameter (`{ requestPayload, payload, error }`). The `payload` contains the decoded response body when it's successfull. When it's failed, the response body is passed in the `error`.
568+
- `callback`: Execute an arbitrary function. The value should be the function to execute. React-admin will call the function with an object as parameter (`{ requestPayload, payload, error }`). The `payload` contains the decoded response body when it's successful. When it's failed, the response body is passed in the `error`.
569569
- `basePath`: This is not a side effect, but it's used internally to compute redirection paths. Set it when you have a redirection side effect.
570570

571571
## Making An Action Undoable

docs/Admin.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -173,8 +173,9 @@ const Menu = ({ resources, onMenuClick, logout }) => (
173173
<div>
174174
{resources.map(resource => (
175175
<MenuItemLink
176+
key={resource.name}
176177
to={`/${resource.name}`}
177-
primaryText={resource.name}
178+
primaryText={resource.options && resource.options.label || resource.name}
178179
leftIcon={createElement(resource.icon)}
179180
onClick={onMenuClick}
180181
/>

docs/Authentication.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ const MyLogoutButton = ({ userLogout, ...rest }) => (
287287
xsmall={
288288
<MenuItem
289289
onClick={userLogout}
290-
{...sanitizeRestProps(rest)}
290+
{...rest}
291291
>
292292
<ExitIcon /> Logout
293293
</MenuItem>
@@ -296,7 +296,7 @@ const MyLogoutButton = ({ userLogout, ...rest }) => (
296296
<Button
297297
onClick={userLogout}
298298
size="small"
299-
{...sanitizeRestProps(rest)}
299+
{...rest}
300300
>
301301
<ExitIcon /> Logout
302302
</Button>

docs/DataProviders.md

-2
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,6 @@ Due to the breaking changes, the following providers are no longer working with
7373
* **[DynamoDb](https://github.com/abiglobalhealth/aor-dynamodb-client)**: [abiglobalhealth/aor-dynamodb-client](https://github.com/abiglobalhealth/aor-dynamodb-client)
7474
* **[Epilogue](https://github.com/dchester/epilogue)**: [dunghuynh/aor-epilogue-client](https://github.com/dunghuynh/aor-epilogue-client)
7575
* **[Firebase](https://firebase.google.com/)**: [sidferreira/aor-firebase-client](https://github.com/sidferreira/aor-firebase-client)
76-
* **[Firebase - Firestore](https://firebase.google.com/docs/firestore)**: [benwinding/react-admin-firebase](https://github.com/benwinding/react-admin-firebase)
77-
* **[JSON API](http://jsonapi.org/)**: [moonlight-labs/aor-jsonapi-client](https://github.com/moonlight-labs/aor-jsonapi-client)
7876
* **[Loopback](http://loopback.io/)**: [kimkha/aor-loopback](https://github.com/kimkha/aor-loopback)
7977
* **[Parse Server](https://github.com/ParsePlatform/parse-server)**: [leperone/aor-parseserver-client](https://github.com/leperone/aor-parseserver-client)
8078
* **[PostgREST](http://postgrest.com/en/v0.4/)**: [tomberek/aor-postgrest-client](https://github.com/tomberek/aor-postgrest-client)

0 commit comments

Comments
 (0)