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

Add ability to create independent store configurations for different lists of same resource #8042

Closed
wants to merge 61 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
364785a
Delete contexts don't send mutation meta
antoinefricker Jul 29, 2022
ae7aa5e
Fix access error
antoinefricker Jul 29, 2022
94a5678
Add meta support for bulk delete buttons
antoinefricker Jul 29, 2022
603ccdc
Update doc
antoinefricker Jul 29, 2022
e55f8de
Comment from PR
antoinefricker Aug 1, 2022
ea98f3c
Fix ArrayInput Adding Previously Removed Item
Aug 3, 2022
c487662
Apply review
Aug 3, 2022
e9bfa4c
Apply review
djhi Aug 4, 2022
83ff11a
Feat: Add filter redirection for pending reviews
arimet Aug 4, 2022
54a483d
Merge pull request #8036 from marmelab/fix-dashboard-redirection
fzaninotto Aug 4, 2022
5bd24ce
Add unit tests
antoinefricker Aug 4, 2022
35a81b9
Unit test corrections
antoinefricker Aug 4, 2022
e36ef26
Merge pull request #8029 from marmelab/fix-array-input-adding-previou…
fzaninotto Aug 4, 2022
4f2e996
Merge pull request #8023 from marmelab/8016-dataprovider-delete-meta
fzaninotto Aug 4, 2022
0847d2b
[Demo] Fix poster category selector shows id instead of name
fzaninotto Aug 4, 2022
ce98e65
[TypeScript] Fix MenuItemLink prop type isn't exported
fzaninotto Aug 4, 2022
0ae5f1f
Merge pull request #8040 from marmelab/fix-MenuItemLink-type
fzaninotto Aug 5, 2022
847e35a
Prepare changelog for v4.2.6
fzaninotto Aug 5, 2022
9592083
v4.2.6
fzaninotto Aug 5, 2022
f956e85
Fix yarn.lock
fzaninotto Aug 5, 2022
9454956
Add `customStoreKey` property
antoinefricker Aug 5, 2022
d379cba
Add feature documentation
antoinefricker Aug 5, 2022
a65472a
[Doc] Improve ImageField, NumberField and SelectField docs
fzaninotto Aug 8, 2022
243e9bc
Document how to sanitize form values
antoinefricker Aug 8, 2022
a286228
Merge pull request #8048 from marmelab/trello753
fzaninotto Aug 8, 2022
db57dd6
Unit tests
antoinefricker Aug 9, 2022
3dd0ac7
replace cloneElement by RecordContext
thibault-barrat Aug 9, 2022
4302137
Merge pull request #8052 from marmelab/7877-fileinput-cloneelement
fzaninotto Aug 9, 2022
ffe8878
add documentation for Vite integration
thibault-barrat Aug 9, 2022
1f6d7a9
add JsonSchemaForm doc
thibault-barrat Aug 9, 2022
c712aa3
Fix: useIsFormInvalid
arimet Aug 9, 2022
1ae6721
remove 'install dependencies' step
thibault-barrat Aug 9, 2022
d45f3b0
Merge pull request #8054 from marmelab/doc-vite
fzaninotto Aug 9, 2022
b384e30
Fix: Update useReferenceInputController test
arimet Aug 9, 2022
e86fedf
Merge pull request #8055 from marmelab/edit-notification
antoinefricker Aug 9, 2022
5dcef17
add form screenshot
thibault-barrat Aug 9, 2022
ddbab79
Merge pull request #8056 from marmelab/doc-json-schema-form
fzaninotto Aug 9, 2022
e467f4a
Fix: useAugmentedForm
arimet Aug 9, 2022
df2c757
Fix: Update eslint errors
arimet Aug 9, 2022
073a8c4
Fix useStore internal state reset when key changes
slax57 Aug 9, 2022
efbdeaf
Fix FormDataConsumer inside SimpleFormIterator adds empty value
fzaninotto Aug 10, 2022
03f081c
Fix: Update JSDoc
arimet Aug 10, 2022
43e7c4c
Merge pull request #8057 from marmelab/useNotifyIsValid
slax57 Aug 10, 2022
f55af51
Add unit test
fzaninotto Aug 10, 2022
f16e6c2
Merge pull request #8045 from marmelab/field-doc-improvement
fzaninotto Aug 10, 2022
d4f4719
Fix infinite re-render
slax57 Aug 10, 2022
6fc2039
Merge pull request #8058 from marmelab/fix-useStore-internal-state-reset
fzaninotto Aug 10, 2022
959b735
Merge pull request #8061 from marmelab/fix-simpleformiterator-formdat…
slax57 Aug 10, 2022
253c8c3
Merge branch 'master' into next
fzaninotto Aug 11, 2022
dd9d095
Add `customStoreKey` property
antoinefricker Aug 5, 2022
d3a29c4
Add feature documentation
antoinefricker Aug 5, 2022
fd26494
Unit tests
antoinefricker Aug 9, 2022
6b997c8
Unit test corrections
antoinefricker Aug 9, 2022
f031fd8
First correction from review
antoinefricker Aug 9, 2022
72800f8
Fix UT
antoinefricker Aug 11, 2022
ee9697b
Update useListController.md
antoinefricker Aug 12, 2022
9518bc3
Add feature documentation
antoinefricker Aug 5, 2022
62e8975
Unit tests
antoinefricker Aug 9, 2022
4169083
Merge branch 'rao8038-custom-list-storekey' of github.com:marmelab/re…
antoinefricker Aug 12, 2022
ec5f3fb
Add feature documentation
antoinefricker Aug 5, 2022
0c277f3
Merge branch 'rao8038-custom-list-storekey' of github.com:marmelab/re…
antoinefricker Aug 12, 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
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# Changelog

## v4.2.6

* Fix `<DeleteButton mutationOptions>` ignores `meta` parameter ([#8023](https://github.com/marmelab/react-admin/pull/8023)) ([septentrion-730n](https://github.com/septentrion-730n))
* Fix `<NumberInput>` state only changes on blur ([#8033](https://github.com/marmelab/react-admin/pull/8033)) ([fzaninotto](https://github.com/fzaninotto))
* Fix `<ArrayInput>` adds previously removed item ([#8029](https://github.com/marmelab/react-admin/pull/8029)) ([djhi](https://github.com/djhi))
* [TypeScript] Fix `<MenuItemLink>` prop type isn't exported ([#8040](https://github.com/marmelab/react-admin/pull/8040)) ([fzaninotto](https://github.com/fzaninotto))
* [Doc] Add Search component ([#8021](https://github.com/marmelab/react-admin/pull/8021)) ([fzaninotto](https://github.com/fzaninotto))
* [Doc] Fix typos in Search documentation ([#8024](https://github.com/marmelab/react-admin/pull/8024)) ([septentrion-730n](https://github.com/septentrion-730n))
* [Demo] Fix Pending reviews link on Dashboard ([#8036](https://github.com/marmelab/react-admin/pull/8036)) ([arimet](https://github.com/arimet))
* [Demo] Fix Category List does not use RecordContext ([#8035](https://github.com/marmelab/react-admin/pull/8035)) ([arimet](https://github.com/arimet))

## v4.2.5

- Fix Input label proptypes and `<DatagridInput>` imports ([#8019](https://github.com/marmelab/react-admin/pull/8019)) by ([megantaylor](https://github.com/megantaylor))
Expand Down
11 changes: 6 additions & 5 deletions docs/Buttons.md
Original file line number Diff line number Diff line change
Expand Up @@ -244,11 +244,11 @@ export const PostList = () => (

![Bulk Delete button](./img/bulk-delete-button.png)

| Prop | Required | Type | Default | Description |
| ------------ | -------- | --------------- | ------------------ | ----------------------------------- |
| `label` | Optional | `string` | 'ra.action.delete' | label or translation message to use |
| `icon` | Optional | `ReactElement` | `<DeleteIcon>` | iconElement, e.g. `<CommentIcon />` |
| `exporter` | Optional | `Function` | - | Override the List exporter function |
| Prop | Required | Type | Default | Description |
| --------------------| -------- | --------------- | ------------------ | ---------------------------------------------------|
| `label` | Optional | `string` | 'ra.action.delete' | label or translation message to use |
| `icon` | Optional | `ReactElement` | `<DeleteIcon>` | iconElement, e.g. `<CommentIcon />` |
| `mutationOptions` | Optional | `object` | null | options for react-query `useMutation` hook |

### `<FilterButton>`

Expand Down Expand Up @@ -277,6 +277,7 @@ Delete the current record after a confirm dialog has been accepted. To be used i
| `confirmContent` | Optional | `ReactNode` | 'ra.message.delete_content' | Message or React component to be used as the body of the confirm dialog |
| `redirect` | Optional | `string | false | Function` | 'list' | Custom redirection after success side effect |
| `translateOptions` | Optional | `{ id?: string, name?: string }` | {} | Custom id and name to be used in the confirm dialog's title |
| `mutationOptions` | Optional | | null | options for react-query `useMutation` hook |

{% raw %}
```jsx
Expand Down
22 changes: 21 additions & 1 deletion docs/Create.md
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,27 @@ export const UserCreate = (props) => {

The `transform` function can also return a `Promise`, which allows you to do all sorts of asynchronous calls (e.g. to the `dataProvider`) during the transformation.

**Tip**: If you want to have different transformations based on the button clicked by the user (e.g. if the creation form displays two submit buttons, one to "save", and another to "save and notify other admins"), you can set the `transform` prop on [the `<SaveButton>` component](./SaveButton.md), too.
**Tip**: If you want to have different transformations based on the button clicked by the user (e.g. if the creation form displays two submit buttons, one to "save", and another to "save and notify other admins"), you can set the `transform` prop on [the `<SaveButton>` component](./SaveButton.md), too.

**Tip**: A frequent usage of the `transform` function is to stripe empty string values returned by the form.

```jsx
export const UserCreate = (props) => {
const transform = (data) => {
const sanitizedData = {};
for (const key in data) {
if (typeof data[key] === "string" && data[key].length === 0) continue;
sanitizedData[key] = data[key];
}
return sanitizedData;
};
return (
<Create {...props} transform={transform}>
...
</Create>
);
}
```

## Adding `meta` To The DataProvider Call

Expand Down
22 changes: 21 additions & 1 deletion docs/Edit.md
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,7 @@ The `transform` function can also return a `Promise`, which allows you to do all

**Tip**: If you want to have different transformations based on the button clicked by the user (e.g. if the creation form displays two submit buttons, one to "save", and another to "save and notify other admins"), you can set the `transform` prop on [the `<SaveButton>` component](./SaveButton.md), too.

**Tip**: `<Edit>`’s transform prop function also get the `previousData` in its second argument:
**Tip**: The `transform` function also get the `previousData` in its second argument:

```jsx
export const UserEdit = (props) => {
Expand All @@ -539,6 +539,26 @@ export const UserEdit = (props) => {
}
```

**Tip**: A frequent usage of the `transform` function is to stripe empty string values returned by the form.

```jsx
export const UserEdit = (props) => {
const transform = (data) => {
const sanitizedData = {};
for (const key in data) {
if (typeof data[key] === "string" && data[key].trim().length === 0) continue;
sanitizedData[key] = data[key];
}
return sanitizedData;
};
return (
<Edit {...props} transform={transform}>
...
</Edit>
);
}
```

## Adding `meta` To The DataProvider Call

You can pass a custom `meta` to the `dataProvider` call, using either `queryOptions`, or `mutationOptions`:
Expand Down
74 changes: 54 additions & 20 deletions docs/ImageField.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ title: "The ImageField Component"

# `<ImageField>`

If you need to display an image based on a path contained in a record field, you can use the `<ImageField />` component:
When you need to display an image based on a path contained in a record field, use the `<ImageField />` component.

## Usage

```jsx
import { ImageField } from 'react-admin';
Expand All @@ -18,9 +20,28 @@ import { ImageField } from 'react-admin';
</div>
```

You can also use `<ImageField>` on fields that contain an array of image objects:

```js
<ImageField source="pictures" src="url" title="desc" />

// Renders the record
// {
// id: 123,
// pictures: [
// { url: 'image1.jpg', desc: 'First image' },
// { url: 'image2.jpg', desc: 'Second image' },
// ]
// } as
<ul>
<li><img src="image1.jpg" title="First image" /></li>
<li><img src="image2.jpg" title="Second image" /></li>
</ul>
```

This field is also often used within the [`<ImageInput />`](./ImageInput.md) component to display a preview.

## Properties
## Props

| Prop | Required | Type | Default | Description |
| ------- | -------- | ------ | ------------ | ---------------------------------------------------------------------------------------- |
Expand All @@ -29,18 +50,23 @@ This field is also often used within the [`<ImageInput />`](./ImageInput.md) com

`<ImageField>` also accepts the [common field props](./Fields.md#common-field-props).

## `sx`: CSS API
## `src`

The `<ImageField>` component accepts the usual `className` prop. You can also override many styles of the inner components thanks to the `sx` property (as most MUI components, see their [documentation about it](https://mui.com/customization/how-to-customize/#overriding-nested-component-styles)). This property accepts the following subclasses:
If the record actually contains an array of images in the property defined by the `source` prop, the `src` prop will be needed to determine the `src` value of the images, for example:

| Rule name | Description |
|-------------------------|--------------------------------------------------------------------------------|
| `& .RaImageField-list` | Applied to the underlying `<ul>` component when `sourceValue` prop is an array |
| `& .RaImageField-image` | Applied to each underlying `<img>` component |
```js
// This is the record
{
pictures: [
{ url: 'image1.jpg', desc: 'First image' },
{ url: 'image2.jpg', desc: 'Second image' },
]
}

To override the style of all instances of `<ImageField>` using the [MUI style overrides](https://mui.com/customization/globals/#css), use the `RaImageField` key.
<ImageField source="pictures" src="url" title="desc" />
```

## Usage
## `title`

The optional `title` prop points to the picture title property, used for both `alt` and `title` attributes. It can either be a hard-written string, or a path within your JSON object:

Expand All @@ -54,16 +80,24 @@ The optional `title` prop points to the picture title property, used for both `a
// renders img title as "Picture", since "Picture" is not a path in previous given object
```

If the record actually contains an array of images in the property defined by the `source` prop, the `src` prop will be needed to determine the `src` value of the images, for example:
## `sx`: CSS API

```js
// This is the record
{
pictures: [
{ url: 'image1.jpg', desc: 'First image' },
{ url: 'image2.jpg', desc: 'Second image' },
]
}
The `<ImageField>` component accepts the usual `className` prop. You can also override many styles of the inner components thanks to the `sx` property (as most MUI components, see their [documentation about it](https://mui.com/customization/how-to-customize/#overriding-nested-component-styles)). This property accepts the following subclasses:

<ImageField source="pictures" src="url" title="desc" />
| Rule name | Description |
|-------------------------|--------------------------------------------------------------------------------|
| `& .RaImageField-list` | Applied to the underlying `<ul>` component when `sourceValue` prop is an array |
| `& .RaImageField-image` | Applied to each underlying `<img>` component |

For instance, to specify a size for the image:

{% raw %}
```jsx
<ImageField
source="thumbnail"
sx={{ '& img': { maxWidth: 50, maxHeight: 50, objectFit: 'contain' } }}
/>
```
{% endraw %}

To override the style of all instances of `<ImageField>` using the [MUI style overrides](https://mui.com/customization/globals/#css), use the `RaImageField` key.
19 changes: 18 additions & 1 deletion docs/Inputs.md
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,23 @@ const dateParser = value => {
<DateInput source="isodate" format={dateFormatter} parse={dateParser} defaultValue={new Date()} />
```

**Tip:** To spread a conversion behaviour to your whole application, you can import a `react-admin`component then re-export them with their `transform` and/or `parse` props set.

```jsx
import * as React from 'react';
import { TextInput } from 'react-admin';

const FilledOrNullTextInput = props => {
return (
<TextInput
{...props}
transform={ v => typeof v === 'string' && v.length === 0 ? null : v }
/>
);
};
export default FilledOrNullTextInput;
```

## Linking Two Inputs

Edition forms often contain linked inputs, e.g. country and city (the choices of the latter depending on the value of the former).
Expand Down Expand Up @@ -513,7 +530,7 @@ import { FormDataConsumer } from 'react-admin';

MUI offers [3 variants for text fields](https://mui.com/material-ui/react-text-field/#basic-textfield): `outlined`, `filled`, and `standard`. The default react-admin theme uses the `filled` variant.

Most Input components pass their additional props down to the root component, which is often an MUI Field component. This means you can pass a `variant` prop to override the varaint of a single input:
Most Input components pass their additional props down to the root component, which is often an MUI Field component. This means you can pass a `variant` prop to override the variant of a single input:

```jsx
<TextInput source="name" variant="outlined" />
Expand Down
70 changes: 70 additions & 0 deletions docs/JsonSchemaForm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
---
layout: default
title: "JsonSchemaForm"
---

# `<JsonSchemaForm>`

This [Enterprise Edition](https://marmelab.com/ra-enterprise)<img class="icon" src="./img/premium.svg" /> component allows to render a form from a JSON Schema description based on [react-jsonschema-form](https://github.com/rjsf-team/react-jsonschema-form).

For instance, to generate the following form:

![JsonSchemaForm](https://marmelab.com/ra-enterprise/modules/assets/jsonschemaform.webp)

Configure the <Edit> view with a <JsonSchemaForm> child as follows:

{% raw %}
```jsx
import { Edit } from "react-admin";
import { JsonSchemaForm } from "@react-admin/ra-form-layout";

const CustomerEdit = () => (
<Edit>
<JsonSchemaForm
schema={{
type: "object",
properties: {
id: { type: "number" },
first_name: { type: "string", title: "First name" },
last_name: { type: "string", minLength: 3 },
dob: { type: "string", format: "date" },
sex: { type: "string", enum: ["male", "female"] },
employer_id: { type: "number" },
occupations: {
type: "array",
items: {
type: "object",
properties: {
name: { type: "string" },
from: { type: "string", format: "date" },
to: { type: "string", format: "date" },
},
},
},
},
required: ["id", "last_name", "employer_id"],
}}
uiSchema={{
id: { "ui:disabled": true },
employer_id: {
"ui:widget": "reference",
"ui:options": {
reference: "employers",
optionText: "name",
},
},
}}
onChange={(change) =>
process.env.NODE_ENV !== "test" && console.log("changed", change)
}
onError={(error) =>
process.env.NODE_ENV !== "test" && console.log("error", error)
}
/>
</Edit>
);
```
{% endraw %}

Check [the `ra-form-layout` documentation](https://marmelab.com/ra-enterprise/modules/ra-form-layout#jsonschemaform) for more details.

Loading