Skip to content

Commit 3ff00f0

Browse files
committed
Fix ReferenceField link is wrong when the record is not yet loaded
Closes marmelab#10301 Supersedes marmelab#10304
1 parent ad1fb56 commit 3ff00f0

File tree

4 files changed

+108
-0
lines changed

4 files changed

+108
-0
lines changed

packages/ra-core/src/routing/useGetPathForRecord.spec.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
InferredShowLink,
88
InferredShowLinkWithAccessControl,
99
NoAuthProvider,
10+
SlowLoading,
1011
} from './useGetPathForRecord.stories';
1112
import { AuthProvider } from '..';
1213

@@ -83,4 +84,11 @@ describe('useGetPathForRecord', () => {
8384
)
8485
).toEqual('/posts/123/show');
8586
});
87+
it('should recompute the path when the record changes', async () => {
88+
render(<SlowLoading />);
89+
await screen.findByText('Show no link');
90+
screen.getByText('Load record').click();
91+
const link = await screen.findByText('Show', { selector: 'a' });
92+
expect(link.getAttribute('href')).toEqual('/posts/123/show');
93+
});
8694
});

packages/ra-core/src/routing/useGetPathForRecord.stories.tsx

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,37 @@ export const InferredShowLink = () => (
8585
</TestMemoryRouter>
8686
);
8787

88+
export const SlowLoading = () => {
89+
const [record, setRecord] = React.useState<any>(undefined);
90+
const handleClick = () => {
91+
setRecord({ id: 123 });
92+
};
93+
return (
94+
<TestMemoryRouter>
95+
<CoreAdminContext>
96+
<ResourceContextProvider value="posts">
97+
<ResourceDefinitionContextProvider
98+
definitions={{
99+
posts: {
100+
name: 'posts',
101+
hasEdit: true,
102+
hasShow: false,
103+
},
104+
}}
105+
>
106+
<RecordContextProvider value={record}>
107+
<div style={{ display: 'flex', gap: 2 }}>
108+
<ShowLink />
109+
</div>
110+
<button onClick={handleClick}>Load record</button>
111+
</RecordContextProvider>
112+
</ResourceDefinitionContextProvider>
113+
</ResourceContextProvider>
114+
</CoreAdminContext>
115+
</TestMemoryRouter>
116+
);
117+
};
118+
88119
export const AccessControlWithLinkTypeProvided = ({
89120
authProvider = {
90121
login: () => Promise.resolve(),

packages/ra-core/src/routing/useGetPathForRecord.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,18 @@ export const useGetPathForRecord = <RecordType extends RaRecord = RaRecord>(
125125
})
126126
: false
127127
);
128+
return;
129+
}
130+
131+
// handle string case
132+
if (link) {
133+
setPath(
134+
createPath({
135+
resource,
136+
id: record.id,
137+
type: link,
138+
})
139+
);
128140
}
129141
}, [
130142
createPath,

packages/ra-ui-materialui/src/field/ReferenceField.stories.tsx

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -837,3 +837,60 @@ const AccessControlUI = ({
837837
</div>
838838
);
839839
};
840+
841+
export const Nested = () => (
842+
<TestMemoryRouter initialEntries={['/comments/1/show']}>
843+
<CoreAdminContext
844+
dataProvider={
845+
{
846+
getMany: async resource => {
847+
if (resource === 'posts') {
848+
await new Promise(resolve =>
849+
setTimeout(resolve, 1000)
850+
);
851+
return { data: [{ id: 2, author_id: 3 }] };
852+
}
853+
if (resource === 'authors') {
854+
await new Promise(resolve =>
855+
setTimeout(resolve, 1000)
856+
);
857+
return { data: [{ id: 3, name: 'John Doe' }] };
858+
}
859+
throw new Error(`Unknown resource ${resource}`);
860+
},
861+
} as any
862+
}
863+
>
864+
<ResourceDefinitionContextProvider
865+
definitions={{
866+
books: {
867+
name: 'books',
868+
hasShow: true,
869+
hasEdit: true,
870+
},
871+
posts: {
872+
name: 'posts',
873+
hasShow: true,
874+
hasEdit: true,
875+
},
876+
authors: {
877+
name: 'books',
878+
hasShow: true,
879+
hasEdit: true,
880+
},
881+
}}
882+
>
883+
<ResourceContextProvider value="comments">
884+
<RecordContextProvider value={{ id: 1, post_id: 2 }}>
885+
<ReferenceField source="post_id" reference="posts">
886+
<ReferenceField
887+
source="author_id"
888+
reference="authors"
889+
/>
890+
</ReferenceField>
891+
</RecordContextProvider>
892+
</ResourceContextProvider>
893+
</ResourceDefinitionContextProvider>
894+
</CoreAdminContext>
895+
</TestMemoryRouter>
896+
);

0 commit comments

Comments
 (0)