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

edit / show title prop: add 'false' and callback choices #9768

Closed
wants to merge 56 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
d85fcb9
update doc
erwanMarmelab Mar 18, 2024
e87f8f4
Merge pull request #9729 from marmelab/update-rbac-doc
fzaninotto Mar 19, 2024
e316639
update component + add story
erwanMarmelab Mar 19, 2024
0190b9b
update story action
erwanMarmelab Mar 19, 2024
cd91baa
test it
erwanMarmelab Mar 19, 2024
5b5a897
document it
erwanMarmelab Mar 19, 2024
8f84a10
add ref to props declaration + make it contitionnal
erwanMarmelab Mar 19, 2024
4802849
fix bug
erwanMarmelab Mar 19, 2024
cb430a7
not set ref during rendering
erwanMarmelab Mar 19, 2024
85d3ec8
rename stories with the prop name
erwanMarmelab Mar 19, 2024
b223430
wrap test with a new describe
erwanMarmelab Mar 19, 2024
8b5bbf3
rename ref variable
erwanMarmelab Mar 19, 2024
4c9c3d4
change dev to trick
erwanMarmelab Mar 19, 2024
96f4e32
apply suggestions
erwanMarmelab Mar 19, 2024
ec44ac5
[Doc] Add video to NumberField
fzaninotto Mar 20, 2024
fad0424
remove unused import in story
erwanMarmelab Mar 21, 2024
6dad685
[Doc] Update "Writing a Data Provider" chapter to include test advice
fzaninotto Mar 21, 2024
a575ade
Add more advice about writing a Data Provider
fzaninotto Mar 21, 2024
d72e025
fix code snippet ts error
erwanMarmelab Mar 21, 2024
c933677
Bump webpack-dev-middleware from 6.1.1 to 6.1.2
dependabot[bot] Mar 21, 2024
e8f6a1e
Merge pull request #9738 from marmelab/doc-data-provider-writing
fzaninotto Mar 25, 2024
26ddb1d
Wording fixes
fzaninotto Mar 25, 2024
3d0aa93
Merge pull request #9731 from marmelab/expose-RichTextInput-editor
fzaninotto Mar 25, 2024
7bce19a
Merge pull request #9739 from marmelab/dependabot/npm_and_yarn/webpac…
fzaninotto Mar 25, 2024
fcbe0c8
fix by another way
erwanMarmelab Mar 26, 2024
8deb419
[Doc] Add video tutorial to DataProviderWriting chapter
fzaninotto Mar 26, 2024
1b52622
Merge pull request #9733 from marmelab/fix/demo-crm-error
fzaninotto Mar 26, 2024
63bf992
Bump express from 4.17.3 to 4.19.2
dependabot[bot] Mar 28, 2024
4328fec
Merge pull request #9747 from marmelab/dependabot/npm_and_yarn/expres…
fzaninotto Mar 28, 2024
a4e541d
Fix typo
fzaninotto Mar 28, 2024
9973583
Add support of variant prop for FilterButton
adguernier Mar 29, 2024
0851a1c
split stories for size and variant
adguernier Mar 29, 2024
f0f09da
remove console.log and rename stories
adguernier Mar 29, 2024
076b037
Merge pull request #9751 from marmelab/fix/add-variant-support-for-fi…
erwanMarmelab Mar 29, 2024
149a39b
Prepare changelog for v4.16.14
fzaninotto Mar 29, 2024
35cc20e
v4.16.14
fzaninotto Mar 29, 2024
91efd68
Fix lock file
fzaninotto Mar 29, 2024
2f5a87e
[Doc] Make tutorial codesandbox more welcoming
fzaninotto Apr 2, 2024
735e8c7
[Doc] Embed "Linking two inputs" video
fzaninotto Apr 3, 2024
767a504
Bump vite from 3.2.8 to 3.2.10
dependabot[bot] Apr 3, 2024
9af5512
Merge pull request #9755 from marmelab/dependabot/npm_and_yarn/vite-3…
slax57 Apr 4, 2024
0682d1f
Fix useGetIdentity regression
djhi Apr 4, 2024
fd2ca41
Merge pull request #9756 from marmelab/fix-use-get-identity
fzaninotto Apr 5, 2024
cec2535
changelog for v4.16.15
slax57 Apr 5, 2024
d37eb8f
v4.16.15
slax57 Apr 5, 2024
944b98d
update yarn.lock
slax57 Apr 5, 2024
90a7993
[Doc]: update JsonSchemaForm doc according to EE one
adguernier Apr 5, 2024
688f807
Proofreading
fzaninotto Apr 8, 2024
0f3a37b
Merge pull request #9758 from marmelab/doc/update-json-schema-form-ac…
fzaninotto Apr 8, 2024
8193ad1
fix TipTp typo
adguernier Apr 8, 2024
582e305
Merge pull request #9759 from marmelab/doc/fix-tiptp-typo
djhi Apr 8, 2024
1c901d8
[Doc] Improve useGetList doc
fzaninotto Apr 8, 2024
05fa91d
[Doc] Make Okta discoverable
fzaninotto Apr 9, 2024
729ee78
[Demo] Fix UI glitch in CRM demo
fzaninotto Apr 9, 2024
607f388
edit / show title prop: add 'false' and callback choices
hiaselhans Apr 10, 2024
595279b
run linter
hiaselhans Apr 10, 2024
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

## v4.16.15

* Fix `useGetIdentity` regression ([#9756](https://github.com/marmelab/react-admin/pull/9756)) ([djhi](https://github.com/djhi))
* Bump vite from 3.2.8 to 3.2.10 ([#9755](https://github.com/marmelab/react-admin/pull/9755)) ([dependabot[bot]](https://github.com/apps/dependabot))

## v4.16.14

* Fix `<FilterButton>` does not support the variant prop ([#9751](https://github.com/marmelab/react-admin/9751)) by ([adguernier](https://github.com/marmelab/adguernier))
* [Demo] Fix error when viewing newly created deals in CRM demo ([#9733](https://github.com/marmelab/react-admin/9733)) by ([erwanMarmelab](https://github.com/marmelab/erwanMarmelab))
* Bump express from 4.17.3 to 4.19.2 ([#9747](https://github.com/marmelab/react-admin/9747)) by ([dependabot](https://github.com/marmelab/dependabot))
* Bump webpack-dev-middleware from 6.1.1 to 6.1.2 ([#9739](https://github.com/marmelab/react-admin/9739)) by ([dependabot](https://github.com/marmelab/dependabot))
* [Doc] Update `<RichTextInput>` to explain how to access the editor object ([#9731](https://github.com/marmelab/react-admin/9731)) by ([erwanMarmelab](https://github.com/marmelab/erwanMarmelab))
* [Doc] Update "Writing a Data Provider" chapter to include test advice ([#9738](https://github.com/marmelab/react-admin/9738)) by ([fzaninotto](https://github.com/marmelab/fzaninotto))
* [Doc] Update RBAC to mention ability to define permissions on an array of resources ([#9729](https://github.com/marmelab/react-admin/9729)) by ([erwanMarmelab](https://github.com/marmelab/erwanMarmelab))

## v4.16.13

* Fix `<AutocompleteInput createLabel>` ([#9712](https://github.com/marmelab/react-admin/pull/9712)) ([fzaninotto](https://github.com/fzaninotto))
Expand Down
2 changes: 1 addition & 1 deletion cypress/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@
"cypress": "^10.9.0",
"cypress-plugin-tab": "^1.0.5",
"cypress-vite": "^1.4.0",
"express": "~4.17.3"
"express": "~4.19.2"
}
}
2 changes: 1 addition & 1 deletion docs/AuthProviderList.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ title: "Supported Auth Provider Backends"
It's very common that your auth logic is so specific that you'll need to write your own `authProvider`. However, the community has built a few open-source Auth Providers that may fit your need:

<div class="providers-list" markdown="1">
- ![auth0 Logo](./img/backend-logos/auth0.svg "auth0 Logo")**[Auth0](https://auth0.com/)**: [marmelab/ra-auth-auth0](https://github.com/marmelab/ra-auth-auth0/blob/main/packages/ra-auth-auth0/Readme.md)
- ![auth0 Logo](./img/backend-logos/auth0.svg "auth0 Logo")**[Auth0 by Okta](https://auth0.com/)**: [marmelab/ra-auth-auth0](https://github.com/marmelab/ra-auth-auth0/blob/main/packages/ra-auth-auth0/Readme.md)
- ![amplify Logo](./img/backend-logos/amplify.svg "amplify Logo")**[AWS Amplify](https://docs.amplify.aws)**: [MrHertal/react-admin-amplify](https://github.com/MrHertal/react-admin-amplify)
- ![cognito Logo](./img/backend-logos/aws.png "cognito Logo")**[AWS Cognito](https://docs.aws.amazon.com/cognito/latest/developerguide/setting-up-the-javascript-sdk.html)**: [marmelab/ra-auth-cognito](https://github.com/marmelab/ra-auth-cognito/blob/main/packages/ra-auth-cognito/Readme.md)
- ![azure Logo](./img/backend-logos/microsoft.svg "azure Logo")**[Azure Active Directory (using MSAL)](https://github.com/AzureAD/microsoft-authentication-library-for-js/tree/dev/lib/msal-browser)**: [marmelab/ra-auth-msal](https://github.com/marmelab/ra-auth-msal/blob/main/packages/ra-auth-msal/Readme.md) ([Tutorial](https://marmelab.com/blog/2023/09/13/active-directory-integration-tutorial.html))
Expand Down
1 change: 1 addition & 0 deletions docs/AuthRBAC.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ Here are a few examples of permissions:

- `{ action: "*", resource: "*" }`: allow everything
- `{ action: "read", resource: "*" }`: allow read actions on all resources
- `{ action: "read", resource: ["companies", "people"] }`: allow read actions on a subset of resources
- `{ action: ["read", "create", "edit", "export"], resource: "companies" }`: allow all actions except delete on companies
- `{ action: ["write"], resource: "game.score", record: { "id": "123" } }`: allow to change the score on a particular game

Expand Down
2 changes: 2 additions & 0 deletions docs/Create.md
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,8 @@ Note: In order to get the `mutationOptions` being considered, you have to set th

## Linking Two Inputs

<iframe src="https://www.youtube-nocookie.com/embed/YkqjydtmfcU" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen style="aspect-ratio: 16 / 9;width:100%;margin-bottom:1em;"></iframe>

Edition forms often contain linked inputs, e.g. country and city (the choices of the latter depending on the value of the former).

React-admin relies on [react-hook-form](https://react-hook-form.com/) for form handling. You can grab the current form values using react-hook-form's [useWatch](https://react-hook-form.com/docs/usewatch) hook.
Expand Down
67 changes: 66 additions & 1 deletion docs/DataProviderWriting.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ title: "Writing A Data Provider"

APIs are so diverse that quite often, none of [the available Data Providers](./DataProviderList.md) suit you API. In such cases, you'll have to write your own Data Provider. Don't worry, it usually takes only a couple of hours.

<iframe src="https://www.youtube-nocookie.com/embed/sciDJAUEu_M" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen style="aspect-ratio: 16 / 9;width:100%;margin-bottom:1em;"></iframe>


The methods of a Data Provider receive a request, and return a promise for a response. Both the request and the response format are standardized.

## Data Provider Methods
Expand Down Expand Up @@ -150,7 +153,7 @@ dataProvider.getMany('posts', { ids: [123, 124, 125] })

## `getManyReference`

React-admin calls `dataProvider.getManyReference()` to fetch several records related to another one.
React-admin calls `dataProvider.getManyReference()` to fetch the records related to another record. Although similar to `getList`, this method is designed for relationships. It is necessary because some APIs require a different query to fetch related records (e.g. `GET /posts/123/comments` to fetch comments related to post 123).

**Interface**

Expand Down Expand Up @@ -425,6 +428,30 @@ export default {
};
```

## Handling Authentication

Your API probably requires some form of authentication (e.g. a token in the `Authorization` header). It's the responsibility of [the `authProvider`](./Authentication.md) to log the user in and obtain the authentication data. React-admin doesn't provide any particular way of communicating this authentication data to the Data Provider. Most of the time, storing the authentication data in the `localStorage` is the best choice - and allows uses to open multiple tabs without having to log in again.

Check the [Handling Authentication](./DataProviders.md#handling-authentication) section in the Data Providers introduction for an example of such a setup.

## Testing Data Provider Methods

A good way to test your data provider is to build a react-admin app with components that depend on it. Here is a list of components calling the data provider methods:

| Method | Components |
| ------------------ | --------- |
| `getList` | [`<List>`](./List.md), [`<ListGuesser>`](./ListGuesser.md), [`<ListBase>`](./ListBase.md), [`<InfiniteList>`](./InfiniteList.md), [`<Count>`](./Count.md), [`<Calendar>`](./Calendar.md), [`<ReferenceInput>`](./ReferenceInput.md), [`<ReferenceArrayInput>`](./ReferenceArrayInput.md), [`<ExportButton>`](./Buttons.md#exportbutton), [`<PrevNextButtons>`](./PrevNextButtons.md) |
| `getOne` | [`<Show>`](./Show.md), [`<ShowGuesser>`](./ShowGuesser.md), [`<ShowBase>`](./ShowBase.md), [`<Edit>`](./Edit.md), [`<EditGuesser>`](./EditGuesser.md), [`<EditBase>`](./EditBase.md) |
| `getMany` | [`<ReferenceField>`](./ReferenceField.md), [`<ReferenceArrayField>`](./ReferenceArrayField.md), [`<ReferenceInput>`](./ReferenceInput.md), [`<ReferenceArrayInput>`](./ReferenceArrayInput.md) |
| `getManyReference` | [`<ReferenceManyField>`](./ReferenceManyField.md), [`<ReferenceOneField>`](./ReferenceOneField.md), [`<ReferenceManyInput>`](./ReferenceManyInput.md), [`<ReferenceOneInput>`](./ReferenceOneInput.md) |
| `create` | [`<Create>`](./Create.md), [`<CreateBase>`](./CreateBase.md), [`<EditableDatagrid>`](./EditableDatagrid.md), [`<CreateInDialogButton>`](./CreateInDialogButton.md) |
| `update` | [`<Edit>`](./Edit.md), [`<EditGuesser>`](./EditGuesser.md), [`<EditBase>`](./EditBase.md), [`<EditableDatagrid>`](./EditableDatagrid.md), [`<EditInDialogButton>`](./EditInDialogButton.md), [`<UpdateButton>`](./UpdateButton.md) |
| `updateMany` | [`<BulkUpdateButton>`](./BulkUpdateButton.md) |
| `delete` | [`<DeleteButton>`](./DeleteButton.md), [`<EditableDatagrid>`](./EditableDatagrid.md) |
| `deleteMany` | [`<BulkDeleteButton>`](./BulkDeleteButton.md) |

A simple react-admin app with one `<Resource>` using [guessers](./Features.md#guessers--scaffolding) for the `list`, `edit`, and `show` pages is a good start.

## The `meta` Parameter

All data provider methods accept a `meta` parameter. React-admin core components never set this `meta` when calling the data provider. It's designed to let you pass additional parameters to your data provider.
Expand Down Expand Up @@ -465,6 +492,44 @@ const { data } = dataProvider.getOne('posts', { id: 123 })

This will cause the Edit view to blink on load. If you have this problem, modify your Data Provider to return the same shape for all methods.

## `fetchJson`: Built-In HTTP Client

Although your Data Provider can use any HTTP client (`fetch`, `axios`, etc.), react-admin suggests using a helper function called `fetchJson` that it provides.

`fetchJson` is a wrapper around the `fetch` API that automatically handles JSON deserialization, rejects when the HTTP response isn't 2XX or 3XX, and throws a particular type of error that allows the UI to display a meaningful notification. `fetchJson` also lets you add an `Authorization` header if you pass a `user` option.

Here is how you can use it in your Data Provider:

```diff
+import { fetchUtils } from 'react-admin';

+const fetchJson = (url, options = {}) => {
+ options.user = {
+ authenticated: true,
+ // use the authentication token from local storage (given the authProvider added it there)
+ token: localStorage.getItem('token')
+ };
+ return fetchUtils.fetchJson(url, options);
+};
// ...

const dataProvider = {
getList: (resource, params) => {
const { page, perPage } = params.pagination;
const { field, order } = params.sort;
const query = {
sort: JSON.stringify([field, order]),
range: JSON.stringify([(page - 1) * perPage, page * perPage - 1]),
filter: JSON.stringify(params.filter),
};
const url = `${apiUrl}/${resource}?${stringify(query)}`;
- return fetch(url, { method: 'GET' });
+ return fetchJson(url, { method: 'GET' });
},
// ...
};
```

## Example REST Implementation

Let's say that you want to map the react-admin requests to a REST backend exposing the following API:
Expand Down
2 changes: 2 additions & 0 deletions docs/Edit.md
Original file line number Diff line number Diff line change
Expand Up @@ -728,6 +728,8 @@ The user will see alerts when other users update or delete the record.

## Linking Two Inputs

<iframe src="https://www.youtube-nocookie.com/embed/YkqjydtmfcU" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen style="aspect-ratio: 16 / 9;width:100%;margin-bottom:1em;"></iframe>

Edition forms often contain linked inputs, e.g. country and city (the choices of the latter depending on the value of the former).

React-admin relies on [react-hook-form](https://react-hook-form.com/) for form handling. You can grab the current form values using react-hook-form's [useWatch](https://react-hook-form.com/docs/usewatch) hook.
Expand Down
2 changes: 2 additions & 0 deletions docs/Form.md
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,8 @@ Check [the `<AutoSave>` component](./AutoSave.md) documentation for more details

## Linking Two Inputs

<iframe src="https://www.youtube-nocookie.com/embed/YkqjydtmfcU" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen style="aspect-ratio: 16 / 9;width:100%;margin-bottom:1em;"></iframe>

Edition forms often contain linked inputs, e.g. country and city (the choices of the latter depending on the value of the former).

React-admin relies on [react-hook-form](https://react-hook-form.com/) for form handling. You can grab the current form values using react-hook-form's [useWatch](https://react-hook-form.com/docs/usewatch) hook.
Expand Down
178 changes: 132 additions & 46 deletions docs/JsonSchemaForm.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,18 @@ title: "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).

## Usage

First, install the `@react-admin/ra-json-schema-form` package:

```sh
npm install --save @react-admin/ra-json-schema-form
# or
yarn add @react-admin/ra-json-schema-form
```

If you have a JSON Schema description of your form based on [react-jsonschema-form](https://github.com/rjsf-team/react-jsonschema-form), you can use the `<JsonSchemaForm>` component to render it.

For instance, to generate the following form:

![JsonSchemaForm](https://marmelab.com/ra-enterprise/modules/assets/jsonschemaform.webp)
Expand All @@ -15,56 +27,130 @@ Configure the `<Edit>` view with a `<JsonSchemaForm>` child as follows:

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

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 %}

`<JsonSchemaForm>` initializes the form with the current `record`, and renders it like `<SimpleForm>` does.

It expects a `schema` prop describing the expected data shape, and a `uiSchema` prop describing the UI.

`<JsonSchemaForm>` is a wrapper around JsonSchema Form's `<Form>` component, so please refer to [JsonSchema Form's documentation](https://react-jsonschema-form.readthedocs.io/en/latest/#usage) for detailed usage.

## UI Widgets

`<JsonSchemaForm>` comes with the following UI widgets:

For `boolean` fields:

- `checkbox` (default)
- `radio`
- `select`

For `string` fields:

- `text` (default)
- `textarea`
- `password`
- `color`

The built-in `string` field also supports the `format` property, and will render an appropriate widget depending on its value:

- `email`: renders an `input[type=email]` element;
- `uri`: renders an `input[type=url]` element;
- `data-url`: Renders an `input[type=file]` element (if the string is part of an array, multiple files will be handled automatically);
- `date`: Renders an `input[type=date]` element;
- `date-time`: Renders an `input[type=datetime-local]` element.

For `number` and `integer` fields, you can also specify the `format` to render an alternative widget:

- `text` (default)
- `updown`
- `range`
- `radio`

`ra-json-schema-form` comes with the an additional UI widget for `string` fields: `reference`. It's the equivalent of [react-admin's `<ReferenceInput>` component](https://marmelab.com/react-admin/ReferenceInput.html). It fetches the foreign key, and uses a relationship to populate the list of options.

Specify the `reference`, `optionText`, and other options through the `ui:options` UI schema directive:

{% raw %}
```tsx
import { Edit } from 'react-admin';
import { JsonSchemaForm } from '@react-admin/ra-json-schema-form';

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>
<Edit>
<JsonSchemaForm
schema={{
type: 'object',
properties: {
id: { type: 'number' },
employer_id: { type: 'number' },
},
}}
uiSchema={{
employer_id: {
'ui:widget': 'reference',
'ui:options': {
reference: 'employers',
optionText: 'name',
},
},
}}
/>
</Edit>
);
```
{% endraw %}

Check [the `ra-json-schema-form` documentation](https://marmelab.com/ra-enterprise/modules/ra-json-schema-form#installation) for more details.
## I18N

`<JsonSchemaForm>` passes all labels, descriptions and errors to react-admin's `translate` function. You can translate the form by providing custom translations via your `i18nProvider`.
Loading
Loading