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

Fix ReferenceField link is wrong when the record is not yet loaded #10309

Merged
merged 1 commit into from
Oct 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 8 additions & 0 deletions packages/ra-core/src/routing/useGetPathForRecord.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
InferredShowLink,
InferredShowLinkWithAccessControl,
NoAuthProvider,
SlowLoading,
} from './useGetPathForRecord.stories';
import { AuthProvider } from '..';

Expand Down Expand Up @@ -83,4 +84,11 @@ describe('useGetPathForRecord', () => {
)
).toEqual('/posts/123/show');
});
it('should recompute the path when the record changes', async () => {
render(<SlowLoading />);
await screen.findByText('Show no link');
screen.getByText('Load record').click();
const link = await screen.findByText('Show', { selector: 'a' });
expect(link.getAttribute('href')).toEqual('/posts/123/show');
});
});
31 changes: 31 additions & 0 deletions packages/ra-core/src/routing/useGetPathForRecord.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,37 @@ export const InferredShowLink = () => (
</TestMemoryRouter>
);

export const SlowLoading = () => {
const [record, setRecord] = React.useState<any>(undefined);
const handleClick = () => {
setRecord({ id: 123 });
};
return (
<TestMemoryRouter>
<CoreAdminContext>
<ResourceContextProvider value="posts">
<ResourceDefinitionContextProvider
definitions={{
posts: {
name: 'posts',
hasEdit: true,
hasShow: false,
},
}}
>
<RecordContextProvider value={record}>
<div style={{ display: 'flex', gap: 2 }}>
<ShowLink />
</div>
<button onClick={handleClick}>Load record</button>
</RecordContextProvider>
</ResourceDefinitionContextProvider>
</ResourceContextProvider>
</CoreAdminContext>
</TestMemoryRouter>
);
};

export const AccessControlWithLinkTypeProvided = ({
authProvider = {
login: () => Promise.resolve(),
Expand Down
12 changes: 12 additions & 0 deletions packages/ra-core/src/routing/useGetPathForRecord.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,18 @@ export const useGetPathForRecord = <RecordType extends RaRecord = RaRecord>(
})
: false
);
return;
}

// handle string case
if (link) {
setPath(
createPath({
resource,
id: record.id,
type: link,
})
);
}
}, [
createPath,
Expand Down
57 changes: 57 additions & 0 deletions packages/ra-ui-materialui/src/field/ReferenceField.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -837,3 +837,60 @@ const AccessControlUI = ({
</div>
);
};

export const Nested = () => (
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This story was added to test the nested case, but the bug isn't there. Nonetheless, the story is useful to show that it's working!

<TestMemoryRouter initialEntries={['/comments/1/show']}>
<CoreAdminContext
dataProvider={
{
getMany: async resource => {
if (resource === 'posts') {
await new Promise(resolve =>
setTimeout(resolve, 1000)
);
return { data: [{ id: 2, author_id: 3 }] };
}
if (resource === 'authors') {
await new Promise(resolve =>
setTimeout(resolve, 1000)
);
return { data: [{ id: 3, name: 'John Doe' }] };
}
throw new Error(`Unknown resource ${resource}`);
},
} as any
}
>
<ResourceDefinitionContextProvider
definitions={{
books: {
name: 'books',
hasShow: true,
hasEdit: true,
},
posts: {
name: 'posts',
hasShow: true,
hasEdit: true,
},
authors: {
name: 'books',
hasShow: true,
hasEdit: true,
},
}}
>
<ResourceContextProvider value="comments">
<RecordContextProvider value={{ id: 1, post_id: 2 }}>
<ReferenceField source="post_id" reference="posts">
<ReferenceField
source="author_id"
reference="authors"
/>
</ReferenceField>
</RecordContextProvider>
</ResourceContextProvider>
</ResourceDefinitionContextProvider>
</CoreAdminContext>
</TestMemoryRouter>
);
Loading