Skip to content

Commit afd9de5

Browse files
authored
Merge pull request #11187 from marmelab/merge-master-5.14.4
Merge master 5.14.4 -> next
2 parents 703d0be + faa3d60 commit afd9de5

36 files changed

Lines changed: 3115 additions & 2201 deletions

File tree

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
# Changelog
22

3+
## 5.14.4
4+
5+
* Fix SavedQuery when `disableSyncWithLocation` is set ([#11173](https://github.com/marmelab/react-admin/pull/11173)) ([ThieryMichel](https://github.com/ThieryMichel))
6+
* Fix `RichTextInput` does not allow nesting unordered and ordered lists ([#11179](https://github.com/marmelab/react-admin/pull/11179)) ([frlruehle](https://github.com/frlruehle))
7+
* Fix compatibility with latest version of `@hookform/resolvers` ([#11186](https://github.com/marmelab/react-admin/pull/11186)) ([slax57](https://github.com/slax57))
8+
* [Doc] Use splat route for TanStack Start setup ([#11182](https://github.com/marmelab/react-admin/pull/11182)) ([WiXSL](https://github.com/WiXSL))
9+
* Fix security warnings due to outdated dependencies ([#11183](https://github.com/marmelab/react-admin/pull/11183)) ([ThieryMichel](https://github.com/ThieryMichel))
10+
* Bump js-yaml from 3.14.1 to 3.14.2 ([#11185](https://github.com/marmelab/react-admin/pull/11185)) ([dependabot[bot]](https://github.com/apps/dependabot))
11+
* Bump dompurify from 3.3.1 to 3.3.2 ([#11184](https://github.com/marmelab/react-admin/pull/11184)) ([dependabot[bot]](https://github.com/apps/dependabot))
12+
* Bump dompurify and @types/dompurify ([#11180](https://github.com/marmelab/react-admin/pull/11180)) ([dependabot[bot]](https://github.com/apps/dependabot))
13+
314
## 5.14.3
415

516
* Add default empty component and i18n messages to `ListGuesser` ([#11165](https://github.com/marmelab/react-admin/pull/11165)) ([WiXSL](https://github.com/WiXSL))

docs/TanStackStart.md

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,12 @@ yarn add react-admin ra-router-tanstack ra-data-json-server
5454

5555
## Adding React-Admin In A Sub Route
5656

57-
TanStack Start uses file-based routing. React-admin generates dynamic routes for each resource (e.g. `/admin/users`, `/admin/users/:id`). To avoid “Not Found” pages, we create explicit routes for the resource paths and render the same admin component in each route.
57+
TanStack Start uses file-based routing. React-admin generates dynamic routes for each resource (e.g. `/admin/users`, `/admin/users/:id`). To avoid creating one TanStack route per react-admin page, use a single splat route.
5858

59-
First, create the admin route at `src/routes/admin.tsx`:
59+
First, create the admin route at `src/routes/admin.$.tsx`:
6060

6161
```tsx
62-
// in src/routes/admin.tsx
62+
// in src/routes/admin.$.tsx
6363
import { createFileRoute } from '@tanstack/react-router';
6464
import {
6565
Admin,
@@ -71,7 +71,7 @@ import jsonServerProvider from 'ra-data-json-server';
7171
import { tanStackRouterProvider } from 'ra-router-tanstack';
7272

7373
const dataProvider = jsonServerProvider('https://jsonplaceholder.typicode.com');
74-
export const Route = createFileRoute('/admin')({ component: App });
74+
export const Route = createFileRoute('/admin/$')({ component: App });
7575

7676
function App() {
7777
return (
@@ -92,7 +92,7 @@ function App() {
9292
export default App;
9393
```
9494

95-
Then create the routes for the resource and its dynamic paths:
95+
Then keep the root route as a simple link to the admin:
9696

9797
```tsx
9898
// in src/routes/index.tsx
@@ -112,22 +112,6 @@ function Home() {
112112
export const Route = createFileRoute('/')({ component: Home });
113113
```
114114

115-
```tsx
116-
// in src/routes/admin.users.tsx
117-
import { createFileRoute } from '@tanstack/react-router';
118-
import App from './admin';
119-
120-
export const Route = createFileRoute('/admin/users')({ component: App });
121-
```
122-
123-
```tsx
124-
// in src/routes/admin.users.$id.tsx
125-
import { createFileRoute } from '@tanstack/react-router';
126-
import App from './admin';
127-
128-
export const Route = createFileRoute('/admin/users/$id')({ component: App });
129-
```
130-
131115

132116
You can now start the app in `development` mode:
133117

@@ -141,7 +125,7 @@ The admin should render at `/admin` on your dev server.
141125

142126
![TanStack Start admin screen](./img/tanstack-admin.png)
143127

144-
**Tip**: If you add more resources, create matching file-based routes for each resource list and edit path under `/admin` and point them to the same `App` component.
128+
**Tip**: With the `/admin/$` route, you don't need to create one TanStack Start route file per react-admin page.
145129

146130
## Removing The TanStack Header
147131

@@ -229,7 +213,7 @@ yarn add @raphiniert/ra-data-postgrest
229213
Finally, update your Admin dataProvider:
230214

231215
```tsx
232-
// in src/routes/admin.tsx
216+
// in src/routes/admin.$.tsx
233217
import { Admin, Resource, ListGuesser, fetchUtils } from 'react-admin';
234218
import postgrestRestProvider from '@raphiniert/ra-data-postgrest';
235219
import { tanStackRouterProvider } from 'ra-router-tanstack';

examples/data-generator/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "data-generator-retail",
3-
"version": "5.14.3",
3+
"version": "5.14.4",
44
"homepage": "https://github.com/marmelab/react-admin/tree/master/examples/data-generator",
55
"bugs": "https://github.com/marmelab/react-admin/issues",
66
"license": "MIT",
@@ -17,7 +17,7 @@
1717
"date-fns": "^3.6.0"
1818
},
1919
"devDependencies": {
20-
"ra-core": "^5.14.3",
20+
"ra-core": "^5.14.4",
2121
"typescript": "^5.1.3",
2222
"zshy": "^0.5.0"
2323
},

examples/simple/package.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "simple",
3-
"version": "5.14.3",
3+
"version": "5.14.4",
44
"private": true,
55
"type": "module",
66
"scripts": {
@@ -17,13 +17,13 @@
1717
"fakerest": "^4.1.3",
1818
"jsonexport": "^3.2.0",
1919
"lodash": "~4.17.5",
20-
"ra-data-fakerest": "^5.14.3",
21-
"ra-i18n-polyglot": "^5.14.3",
22-
"ra-input-rich-text": "^5.14.3",
23-
"ra-language-english": "^5.14.3",
24-
"ra-language-french": "^5.14.3",
20+
"ra-data-fakerest": "^5.14.4",
21+
"ra-i18n-polyglot": "^5.14.4",
22+
"ra-input-rich-text": "^5.14.4",
23+
"ra-language-english": "^5.14.4",
24+
"ra-language-french": "^5.14.4",
2525
"react": "^18.3.1",
26-
"react-admin": "^5.14.3",
26+
"react-admin": "^5.14.4",
2727
"react-dom": "^18.3.1",
2828
"react-hook-form": "^7.65.0",
2929
"react-router": "^6.28.1",

lerna.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
2-
"lerna": "2.5.1",
32
"packages": ["examples/data-generator", "examples/simple", "packages/*"],
4-
"version": "5.14.3",
5-
"npmClient": "yarn"
3+
"version": "5.14.4",
4+
"npmClient": "yarn",
5+
"$schema": "node_modules/lerna/schemas/lerna-schema.json"
66
}

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,11 @@
7272
"globals": "^16.0.0",
7373
"husky": "^2.3.0",
7474
"jest": "^29.5.0",
75-
"jest-circus": "29.5.0",
75+
"jest-circus": "^29.5.0",
7676
"jest-environment-jsdom": "^29.5.0",
77-
"jest-resolve": "29.5.0",
77+
"jest-resolve": "^29.5.0",
7878
"jest-watch-typeahead": "2.2.2",
79-
"lerna": "~7.1.3",
79+
"lerna": "^9.0.5",
8080
"lint-staged": "^13.0.3",
8181
"lodash": "^4.17.21",
8282
"lolex": "~2.3.2",

packages/create-react-admin/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "create-react-admin",
33
"description": "A CLI to quickly start a new react-admin project",
4-
"version": "5.14.3",
4+
"version": "5.14.4",
55
"license": "MIT",
66
"bin": "lib/cli.js",
77
"type": "module",

packages/ra-core/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ra-core",
3-
"version": "5.14.3",
3+
"version": "5.14.4",
44
"description": "Core components of react-admin, a frontend Framework for building admin applications on top of REST services, using ES6, React",
55
"files": [
66
"*.md",
@@ -38,7 +38,7 @@
3838
"build": "zshy --silent"
3939
},
4040
"devDependencies": {
41-
"@hookform/resolvers": "^3.2.0",
41+
"@hookform/resolvers": "^5.2.2",
4242
"@tanstack/react-query": "^5.90.2",
4343
"@tanstack/react-query-devtools": "^5.90.2",
4444
"@testing-library/react": "^15.0.7",
@@ -58,7 +58,7 @@
5858
"react-router-dom": "^6.28.1",
5959
"typescript": "^5.1.3",
6060
"yup": "^0.32.11",
61-
"zod": "^3.22.1",
61+
"zod": "^4.3.6",
6262
"zshy": "^0.5.0"
6363
},
6464
"peerDependencies": {

packages/ra-core/src/form/Form.spec.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -871,7 +871,9 @@ describe('Form', () => {
871871
const translate = jest.spyOn(i18nProvider, 'translate');
872872
render(<ZodResolver i18nProvider={i18nProvider} />);
873873
fireEvent.click(screen.getByText('Submit'));
874-
await screen.findByText('Required');
874+
await screen.findByText(
875+
'Invalid input: expected string, received undefined'
876+
);
875877
await screen.findByText('This field is required');
876878
await screen.findByText('This field must be provided');
877879
await screen.findByText('app.validation.missing');

packages/ra-core/src/form/Form.stories.tsx

Lines changed: 66 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import {
66
} from 'react-hook-form';
77
import { zodResolver } from '@hookform/resolvers/zod';
88
import * as z from 'zod';
9+
import { yupResolver } from '@hookform/resolvers/yup';
10+
import * as yup from 'yup';
911
import polyglotI18nProvider from 'ra-i18n-polyglot';
1012
import englishMessages from 'ra-language-english';
1113
import {
@@ -273,14 +275,10 @@ export const InputLevelValidation = ({
273275

274276
const zodSchema = z.object({
275277
defaultMessage: z.string(), //.min(1),
276-
customMessage: z.string({
277-
required_error: 'This field is required',
278-
}),
279-
customMessageTranslationKey: z.string({
280-
required_error: 'app.validation.required',
281-
}),
278+
customMessage: z.string({ error: 'This field is required' }),
279+
customMessageTranslationKey: z.string({ error: 'app.validation.required' }),
282280
missingCustomMessageTranslationKey: z.string({
283-
required_error: 'app.validation.missing',
281+
error: 'app.validation.missing',
284282
}),
285283
});
286284

@@ -308,6 +306,67 @@ export const ZodResolver = ({
308306
);
309307
};
310308

309+
type Schema = z.infer<typeof zodSchema>;
310+
311+
export const ZodResolverWithSchema = ({
312+
i18nProvider = defaultI18nProvider,
313+
}: {
314+
i18nProvider?: I18nProvider;
315+
}) => {
316+
const [result, setResult] = React.useState<any>();
317+
return (
318+
<CoreAdminContext i18nProvider={i18nProvider}>
319+
<Form<Schema>
320+
record={{}}
321+
onSubmit={data => setResult(data)}
322+
resolver={zodResolver(zodSchema)}
323+
>
324+
<Input source="defaultMessage" />
325+
<Input source="customMessage" />
326+
<Input source="customMessageTranslationKey" />
327+
<Input source="missingCustomMessageTranslationKey" />
328+
<button type="submit">Submit</button>
329+
</Form>
330+
<pre>{JSON.stringify(result, null, 2)}</pre>
331+
</CoreAdminContext>
332+
);
333+
};
334+
335+
const yupSchema = yup.object({
336+
defaultMessage: yup.string().required(),
337+
customMessage: yup.string().required('This field is required'),
338+
customMessageTranslationKey: yup
339+
.string()
340+
.required('app.validation.required'),
341+
missingCustomMessageTranslationKey: yup
342+
.string()
343+
.required('app.validation.missing'),
344+
});
345+
346+
export const YupResolver = ({
347+
i18nProvider = defaultI18nProvider,
348+
}: {
349+
i18nProvider?: I18nProvider;
350+
}) => {
351+
const [result, setResult] = React.useState<any>();
352+
return (
353+
<CoreAdminContext i18nProvider={i18nProvider}>
354+
<Form
355+
record={{}}
356+
onSubmit={data => setResult(data)}
357+
resolver={yupResolver(yupSchema)}
358+
>
359+
<Input source="defaultMessage" />
360+
<Input source="customMessage" />
361+
<Input source="customMessageTranslationKey" />
362+
<Input source="missingCustomMessageTranslationKey" />
363+
<button type="submit">Submit</button>
364+
</Form>
365+
<pre>{JSON.stringify(result, null, 2)}</pre>
366+
</CoreAdminContext>
367+
);
368+
};
369+
311370
const FormUnderTest = () => {
312371
const navigate = useNavigate();
313372
return (

0 commit comments

Comments
 (0)