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

Can set order value for SET_SORT action #2855

Closed
wants to merge 47 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
aeb8acd
Ensure that the inputValue is an array and fix #2361
tiagoschenkel Feb 7, 2019
3e58c94
Force the Popper component to reposition the popup when the input is …
tiagoschenkel Feb 7, 2019
33fafcf
Avoid to redraw Popper component when inputEl is not moving
tiagoschenkel Feb 8, 2019
f0a7e91
Simplify internal logic of updateAnchorEl method
tiagoschenkel Feb 8, 2019
82b134a
Update UnitTesting.md
mexitalian Feb 12, 2019
eed959d
Merge pull request #2872 from mexitalian/patch-1
fzaninotto Feb 13, 2019
429c4b6
Fix bad GET_MANY query for ra-data-json-server using a multiple id fi…
paradoxxxzero Feb 13, 2019
8e2fba3
[RFR] Finalize i18n Migration to TypeScript
djhi Feb 13, 2019
87a5681
[RFR] Migrate ra-core form code to TypeScript
djhi Feb 13, 2019
5d953e6
[RFR] Migrate inference code to TypeScript
djhi Feb 13, 2019
e731472
Merge pull request #2874 from marmelab/typescript-migration-i18n
fzaninotto Feb 13, 2019
6f19bb3
Merge pull request #2879 from marmelab/typescript-migration-inference
fzaninotto Feb 13, 2019
59e179c
Review
djhi Feb 13, 2019
b2ea565
Better memoize function typings
djhi Feb 13, 2019
f08bf85
Merge pull request #2878 from marmelab/typescript-migration-form
fzaninotto Feb 13, 2019
5fda66c
[WIP] Migrate ra-core controllers to TypeScript
djhi Feb 13, 2019
7dc064b
Missing index file
djhi Feb 13, 2019
7678936
Inputs
djhi Feb 13, 2019
d0fab37
Fix typo
adibnaya Feb 13, 2019
7a629a1
Views
djhi Feb 13, 2019
a8e44ce
Merge pull request #2882 from adibnaya/patch-2
Feb 13, 2019
af66dbb
Better typing for dispatchers
djhi Feb 14, 2019
1be9fb5
Fix list typings
djhi Feb 14, 2019
a2201e1
Accumulate typings
djhi Feb 14, 2019
459ba28
Merge pull request #2873 from paradoxxxzero/ra-data-json-server-get-m…
fzaninotto Feb 15, 2019
3b67ba8
Corrected prop types for ArrayInput
kujon Feb 18, 2019
f88346f
Merge pull request #2898 from kujon/correct_prop_types
Feb 20, 2019
274acf9
Review
Feb 20, 2019
4351e2b
Fix create controller
Feb 20, 2019
eb3f56d
Added redux-form types
Feb 20, 2019
458ae99
Accept strings and numbers as identifiers for record maps
Feb 20, 2019
44970e7
Review Props
djhi Feb 20, 2019
e7cb8ec
add a note about CloneButton component to docs
mnlbox Feb 20, 2019
e6c89bc
code formatting
fzaninotto Feb 20, 2019
25719af
Review ShowController props
djhi Feb 20, 2019
eecedcc
Merge pull request #2881 from marmelab/typescript-migration-controllers
fzaninotto Feb 20, 2019
b3f450d
Fix typo in tutorial.md
noobling Feb 21, 2019
878d6c6
Merge pull request #2906 from noobling/patch-1
Feb 21, 2019
1505df4
Merge pull request #2904 from mnlbox/master
fzaninotto Feb 21, 2019
be20c55
Merge pull request #2860 from tiagoschenkel/issue-2259
Feb 21, 2019
2f82028
Avoid unnecessary redraws of AutocompleteArrayInputChip
tiagoschenkel Feb 21, 2019
c31ce36
Merge pull request #2861 from tiagoschenkel/issue-2361
fzaninotto Feb 22, 2019
20dbe7c
Prepare changelog for 2.7.2
fzaninotto Feb 22, 2019
b2f1a6d
v2.7.2
fzaninotto Feb 22, 2019
cc1dbec
change SET_SORT reducer to accept a order value.
frankPairs Feb 6, 2019
34c1adc
impleemnt SET_SORT queryReduucer tests.
frankPairs Feb 6, 2019
0b764f4
fix some wrong titles from queryReducer tests.
frankPairs Feb 6, 2019
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
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
# Changelog

## v2.7.2

* Fix JSONPlaceHolder name typo in Tutorial ([2906](https://github.com/marmelab/react-admin/pull/2906)) ([noobling](https://github.com/noobling))
* Fix `<CloneButton>` documentation missing warning ([2904](https://github.com/marmelab/react-admin/pull/2904)) ([mnlbox](https://github.com/mnlbox))
* Fix prop types for `<ArrayInput>` ([2898](https://github.com/marmelab/react-admin/pull/2898)) ([kujon](https://github.com/kujon))
* Fix typo in jsDoc in Tutorial ([2882](https://github.com/marmelab/react-admin/pull/2882)) ([adibnaya](https://github.com/adibnaya))
* Fix `GET_MANY` in `ra-data-json-server` data provider returns too many results ([2873](https://github.com/marmelab/react-admin/pull/2873)) ([paradoxxxzero](https://github.com/paradoxxxzero))
* Fix import path typo in Unit Testing documentation ([2872](https://github.com/marmelab/react-admin/pull/2872)) ([mexitalian](https://github.com/mexitalian))
* Fix `<AutocompleteArrayInput>` throws an error when receiving an empty value ([2861](https://github.com/marmelab/react-admin/pull/2861)) ([tiagoschenkel](https://github.com/tiagoschenkel))
* Fix `<AutocompleteArrayInput>` shows choices in a wrong position when input element moves to another location ([2860](https://github.com/marmelab/react-admin/pull/2860)) ([tiagoschenkel](https://github.com/tiagoschenkel))
* Migrate ra-core controllers to TypeScript ([2881](https://github.com/marmelab/react-admin/pull/2881)) ([djhi](https://github.com/djhi))
* Migrate ra-core inference to TypeScript ([2879](https://github.com/marmelab/react-admin/pull/2879)) ([djhi](https://github.com/djhi))
* Migrate ra-core form to TypeScript ([2878](https://github.com/marmelab/react-admin/pull/2878)) ([djhi](https://github.com/djhi))
* Migrate ra-core i18n Migration to TypeScript ([2874](https://github.com/marmelab/react-admin/pull/2874)) ([djhi](https://github.com/djhi))

## v2.7.1

* Fix typo in `ra-data-graphql-simple` documentation ([2863](https://github.com/marmelab/react-admin/pull/2863)) ([EricTousignant](https://github.com/EricTousignant))
Expand Down
2 changes: 2 additions & 0 deletions docs/CreateEdit.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@ const PostList = props => (

Alternately, you may need to prepopulate a record based on a *related* record. For instance, in a `PostList` component, you may want to display a button to create a comment related to the current post. Clicking on that button would lead to a `CommentCreate` page where the `post_id` is preset to the id of the Post.

**Note** `<CloneButton>` is designed to be used in an edit view `<Actions>` component, not inside a `<Toolbar>`. The `Toolbar` is basically for submitting the form, not for going to another resource.

By default, the `<Create>` view starts with an empty `record`. However, if the `location` object (injected by [react-router](https://reacttraining.com/react-router/web/api/location)) contains a `record` in its `state`, the `<Create>` view uses that `record` instead of the empty object. That's how the `<CloneButton>` works behind the hood.

That means that if you want to create a link to a creation form, presetting *some* values, all you have to do is to set the location `state`. React-router provides the `<Link>` component for that:
Expand Down
6 changes: 3 additions & 3 deletions docs/Tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -764,7 +764,7 @@ This works exactly the way you expect. The lesson here is that react-admin takes

## Connecting To A Real API

Here is the elephant in the room of this tutorial. In real world projects, the dialect of your API (REST? GraphQL? Something else?) won't match the JSONPLaceholder dialect. Writing a Data Provider is probably the first thing you'll have to do to make react-admin work. Depending on your API, this can require a few hours of additional work.
Here is the elephant in the room of this tutorial. In real world projects, the dialect of your API (REST? GraphQL? Something else?) won't match the JSONPlaceholder dialect. Writing a Data Provider is probably the first thing you'll have to do to make react-admin work. Depending on your API, this can require a few hours of additional work.

React-admin delegates every data query to a Data Provider function. This function must simply return a promise for the result. This gives extreme freedom to map any API dialect, add authentication headers, use endpoints from several domains, etc.

Expand Down Expand Up @@ -800,7 +800,7 @@ import { stringify } from 'query-string';
const API_URL = 'my.api.url';

/**
* @param {String} type One of the constants appearing at the top if this file, e.g. 'UPDATE'
* @param {String} type One of the constants appearing at the top of this file, e.g. 'UPDATE'
* @param {String} resource Name of the resource to fetch, e.g. 'posts'
* @param {Object} params The Data Provider request params, depending on the type
* @returns {Object} { url, options } The HTTP request parameters
Expand Down Expand Up @@ -857,7 +857,7 @@ const convertDataProviderRequestToHTTP = (type, resource, params) => {

/**
* @param {Object} response HTTP response from fetch()
* @param {String} type One of the constants appearing at the top if this file, e.g. 'UPDATE'
* @param {String} type One of the constants appearing at the top of this file, e.g. 'UPDATE'
* @param {String} resource Name of the resource to fetch, e.g. 'posts'
* @param {Object} params The Data Provider request params, depending on the type
* @returns {Object} Data Provider response
Expand Down
2 changes: 1 addition & 1 deletion docs/UnitTesting.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Luckily, react-admin provides access to a `TestContext` wrapper component that c

```jsx
import React from 'react';
import { TestContext } from 'ra-core';
import { TestContext } from 'react-admin';
import { mount } from 'enzyme';
import MyCustomEditView from './my-custom-edit-view';

Expand Down
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@
"examples/data-generator",
"packages/*"
],
"version": "2.7.1"
"version": "2.7.2"
}
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@
"lolex": "~2.3.2",
"prettier": "~1.16.4",
"raf": "~3.4.0",
"ts-jest": "^23.10.4",
"tslint": "^5.11.0",
"tslint-config-prettier": "^1.15.0",
"tslint-plugin-prettier": "^2.0.0",
"ts-jest": "^23.10.5",
"tslint": "^5.12.1",
"tslint-config-prettier": "^1.18.0",
"tslint-plugin-prettier": "^2.0.1",
"tslint-react": "^3.6.0",
"wait-on": "^2.1.0"
},
Expand All @@ -63,6 +63,6 @@
"cypress"
],
"dependencies": {
"typescript": "^3.1.3"
"typescript": "^3.3.3"
}
}
3 changes: 2 additions & 1 deletion packages/ra-core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ra-core",
"version": "2.7.1",
"version": "2.7.2",
"description": "Core components of react-admin, a frontend Framework for building admin applications on top of REST services, using ES6, React",
"files": [
"*.md",
Expand Down Expand Up @@ -30,6 +30,7 @@
"@types/node-polyglot": "^0.4.31",
"@types/react-router": "^4.4.1",
"@types/recompose": "^0.27.0",
"@types/redux-form": "^7.5.2",
"cross-env": "^5.2.0",
"enzyme": "~3.7.0",
"enzyme-adapter-react-16": "~1.6.0",
Expand Down
9 changes: 5 additions & 4 deletions packages/ra-core/src/actions/accumulateActions.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { crudGetMany, crudGetMatching } from './dataActions';
import { Pagination, Sort, Identifier } from '../types';

export const CRUD_GET_MANY_ACCUMULATE = 'RA/CRUD_GET_MANY_ACCUMULATE';

export interface CrudGetManyAccumulateAction {
readonly type: typeof CRUD_GET_MANY_ACCUMULATE;
readonly payload: {
resource: string;
ids: [];
ids: Identifier[];
};
readonly meta: {
accumulate: any;
Expand All @@ -15,7 +16,7 @@ export interface CrudGetManyAccumulateAction {

export const crudGetManyAccumulate = (
resource: string,
ids: []
ids: Identifier[]
): CrudGetManyAccumulateAction => ({
type: CRUD_GET_MANY_ACCUMULATE,
payload: { resource, ids },
Expand All @@ -36,8 +37,8 @@ export interface CrudGetMatchingAccumulateAction {
export const crudGetMatchingAccumulate = (
reference: string,
relatedTo: string,
pagination: { page: number; perPage: number },
sort: { field: string; order: string },
pagination: Pagination,
sort: Sort,
filter: object
): CrudGetMatchingAccumulateAction => {
const action = crudGetMatching(
Expand Down
7 changes: 4 additions & 3 deletions packages/ra-core/src/actions/listActions.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export const CRUD_CHANGE_LIST_PARAMS = 'RA/CRUD_CHANGE_LIST_PARAMS';

interface Params {
export interface ListParams {
sort: string;
order: string;
page: number;
Expand All @@ -10,12 +10,13 @@ interface Params {

export interface ChangeListParamsAction {
readonly type: typeof CRUD_CHANGE_LIST_PARAMS;
readonly payload: Params;
readonly payload: ListParams;
readonly meta: { resource: string };
}

export const changeListParams = (
resource: string,
params: Params
params: ListParams
): ChangeListParamsAction => ({
type: CRUD_CHANGE_LIST_PARAMS,
payload: params,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,27 @@
import React from 'react';
import { shallow } from 'enzyme';

import { CreateController } from './CreateController';
import { UnconnectedCreateController as CreateController } from './CreateController';

describe('CreateController', () => {
describe('Presetting the record from the location', () => {
const defaultProps = {
basePath: '',
crudCreate: () => {},
crudCreate: jest.fn(),
hasCreate: true,
hasEdit: true,
hasList: true,
hasShow: true,
isLoading: false,
location: {},
match: {},
location: {
pathname: '/foo',
search: undefined,
state: undefined,
hash: undefined,
},
match: { isExact: true, path: '/foo', params: undefined, url: '' },
resource: 'foo',
title: 'Foo',
translate: x => x,
};

Expand All @@ -33,7 +43,10 @@ describe('CreateController', () => {
const props = {
...defaultProps,
children: childrenMock,
location: { state: { record: { foo: 'bar' } } },
location: {
...defaultProps.location,
state: { record: { foo: 'bar' } },
},
};

shallow(<CreateController {...props} />);
Expand All @@ -47,7 +60,10 @@ describe('CreateController', () => {
const props = {
...defaultProps,
children: childrenMock,
location: { search: '?foo=baz&array[]=1&array[]=2' },
location: {
...defaultProps.location,
search: '?foo=baz&array[]=1&array[]=2',
},
};

shallow(<CreateController {...props} />);
Expand All @@ -64,6 +80,7 @@ describe('CreateController', () => {
...defaultProps,
children: childrenMock,
location: {
...defaultProps.location,
state: { record: { foo: 'bar' } },
search: '?foo=baz',
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,43 @@
import { Component } from 'react';
import PropTypes from 'prop-types';
import { Component, ReactNode } from 'react';
import { connect } from 'react-redux';
import compose from 'recompose/compose';
import inflection from 'inflection';
import { parse } from 'query-string';

import translate from '../i18n/translate';
import withTranslate from '../i18n/translate';
import { crudCreate as crudCreateAction } from '../actions';
import checkMinimumRequiredProps from './checkMinimumRequiredProps';
import { Location } from 'history';
import { match as Match } from 'react-router';
import { Record, Translate, Dispatch } from '../types';
import { RedirectionSideEffect } from '../sideEffect';

interface ChildrenFuncParams {
isLoading: boolean;
defaultTitle: string;
save: (record: Partial<Record>, redirect: RedirectionSideEffect) => void;
resource: string;
basePath: string;
record?: Partial<Record>;
redirect: RedirectionSideEffect;
translate: Translate;
}

interface Props {
basePath: string;
children: (params: ChildrenFuncParams) => ReactNode;
crudCreate: Dispatch<typeof crudCreateAction>;
hasCreate?: boolean;
hasEdit?: boolean;
hasList?: boolean;
hasShow?: boolean;
isLoading: boolean;
location: Location;
match: Match;
record?: Partial<Record>;
resource: string;
translate: Translate;
}

/**
* Page component for the Create view
Expand Down Expand Up @@ -50,7 +80,13 @@ import checkMinimumRequiredProps from './checkMinimumRequiredProps';
* );
* export default App;
*/
export class CreateController extends Component {
export class UnconnectedCreateController extends Component<Props> {
public static defaultProps: Partial<Props> = {
record: {},
};

private record: Partial<Record>;

constructor(props) {
super(props);
const {
Expand All @@ -67,12 +103,16 @@ export class CreateController extends Component {

defaultRedirectRoute() {
const { hasShow, hasEdit } = this.props;
if (hasEdit) return 'edit';
if (hasShow) return 'show';
if (hasEdit) {
return 'edit';
}
if (hasShow) {
return 'show';
}
return 'list';
}

save = (record, redirect) => {
save = (record: Partial<Record>, redirect: RedirectionSideEffect) => {
this.props.crudCreate(
this.props.resource,
record,
Expand All @@ -90,7 +130,9 @@ export class CreateController extends Component {
translate,
} = this.props;

if (!children) return null;
if (!children) {
return null;
}

const resourceName = translate(`resources.${resource}.name`, {
smart_count: 1,
Expand All @@ -112,38 +154,19 @@ export class CreateController extends Component {
}
}

CreateController.propTypes = {
basePath: PropTypes.string.isRequired,
children: PropTypes.func.isRequired,
crudCreate: PropTypes.func.isRequired,
hasCreate: PropTypes.bool,
hasEdit: PropTypes.bool,
hasList: PropTypes.bool,
hasShow: PropTypes.bool,
isLoading: PropTypes.bool.isRequired,
location: PropTypes.object.isRequired,
match: PropTypes.object.isRequired,
record: PropTypes.object,
resource: PropTypes.string.isRequired,
title: PropTypes.any,
translate: PropTypes.func.isRequired,
};

CreateController.defaultProps = {
record: {},
};

function mapStateToProps(state) {
return {
isLoading: state.admin.loading > 0,
};
}

export default compose(
const CreateController = compose(
checkMinimumRequiredProps('Create', ['basePath', 'location', 'resource']),
connect(
mapStateToProps,
{ crudCreate: crudCreateAction }
),
translate
)(CreateController);
withTranslate
)(UnconnectedCreateController);

export default CreateController;
Loading