diff --git a/examples/simple/src/comments/CommentList.tsx b/examples/simple/src/comments/CommentList.tsx
index fcefb451c29..2ff2894a68c 100644
--- a/examples/simple/src/comments/CommentList.tsx
+++ b/examples/simple/src/comments/CommentList.tsx
@@ -11,6 +11,7 @@ import {
CardHeader,
Grid,
Toolbar,
+ Typography,
useMediaQuery,
} from '@material-ui/core';
import { makeStyles } from '@material-ui/core/styles';
@@ -160,13 +161,14 @@ const CommentGrid = () => {
- {translate('comment.list.about')}
+
+ {translate('comment.list.about')}
+
', () => {
@@ -30,7 +29,7 @@ describe('', () => {
}
);
expect(children.mock.calls[0][0]).toMatchObject({
- basePath: '',
+ basePath: '/bar',
currentSort: { field: 'id', order: 'ASC' },
loaded: false,
loading: true,
@@ -49,7 +48,6 @@ describe('', () => {
resource="foo"
reference="bar"
source="barIds"
- basePath=""
>
{children}
,
@@ -70,7 +68,7 @@ describe('', () => {
);
expect(children.mock.calls[0][0]).toMatchObject({
- basePath: '',
+ basePath: '/bar',
currentSort: { field: 'id', order: 'ASC' },
loaded: false,
loading: true,
@@ -93,7 +91,6 @@ describe('', () => {
resource="foo"
reference="bar"
source="barIds"
- basePath=""
>
{children}
,
@@ -111,7 +108,7 @@ describe('', () => {
}
);
expect(children.mock.calls[0][0]).toMatchObject({
- basePath: '',
+ basePath: '/bar',
currentSort: { field: 'id', order: 'ASC' },
loaded: true,
loading: true,
@@ -132,7 +129,6 @@ describe('', () => {
resource="foo"
reference="bar"
source="barIds"
- basePath=""
>
{children}
,
@@ -150,7 +146,7 @@ describe('', () => {
}
);
expect(children.mock.calls[0][0]).toMatchObject({
- basePath: '',
+ basePath: '/bar',
currentSort: { field: 'id', order: 'ASC' },
loaded: true,
loading: true,
@@ -182,7 +178,6 @@ describe('', () => {
resource="foo"
reference="bar"
source="barIds"
- basePath=""
>
{children}
@@ -212,7 +207,6 @@ describe('', () => {
resource="foo"
reference="bar"
source="barIds"
- basePath=""
>
{children}
,
@@ -230,7 +224,7 @@ describe('', () => {
}
);
expect(children.mock.calls[0][0]).toMatchObject({
- basePath: '',
+ basePath: '/bar',
currentSort: { field: 'id', order: 'ASC' },
loaded: true,
loading: true,
@@ -251,7 +245,6 @@ describe('', () => {
resource="foo"
reference="bar"
source="barIds"
- basePath=""
>
{children}
,
@@ -271,7 +264,7 @@ describe('', () => {
}
);
expect(children.mock.calls[0][0]).toMatchObject({
- basePath: '',
+ basePath: '/bar',
currentSort: { field: 'id', order: 'ASC' },
loaded: true,
loading: true,
diff --git a/packages/ra-core/src/controller/field/ReferenceArrayFieldController.tsx b/packages/ra-core/src/controller/field/ReferenceArrayFieldController.tsx
index b68e5feed19..e82a6a4950e 100644
--- a/packages/ra-core/src/controller/field/ReferenceArrayFieldController.tsx
+++ b/packages/ra-core/src/controller/field/ReferenceArrayFieldController.tsx
@@ -5,7 +5,7 @@ import { ListControllerProps } from '../useListController';
import { Record, SortPayload } from '../../types';
interface Props {
- basePath: string;
+ basePath?: string;
filter?: any;
page?: number;
perPage?: number;
diff --git a/packages/ra-core/src/controller/field/getResourceLinkPath.ts b/packages/ra-core/src/controller/field/getResourceLinkPath.ts
index 6f9d04cddef..dc41f78c04b 100644
--- a/packages/ra-core/src/controller/field/getResourceLinkPath.ts
+++ b/packages/ra-core/src/controller/field/getResourceLinkPath.ts
@@ -8,13 +8,16 @@ export type LinkToFunctionType = (record: Record, reference: string) => string;
export type LinkToType = string | boolean | LinkToFunctionType;
interface Option {
- basePath: string;
- record?: Record;
source: string;
reference: string;
resource: string;
+ basePath?: string;
+ record?: Record;
link?: LinkToType;
- linkType?: LinkToType; // deprecated, use link instead
+ /**
+ * @deprecated use link instead
+ */
+ linkType?: LinkToType;
}
/**
@@ -31,7 +34,7 @@ interface Option {
* },
* resource: 'comments',
* source: 'userId',
- * });
+ * }); // '/users/7'
*
* @param {Object} option
* @param {string} option.basePath basepath to current resource
@@ -42,38 +45,32 @@ interface Option {
* @param {string} option.resource The current resource name
* @param {string} option.source The key of the linked resource identifier
*
- * @returns {string | false} The reference props
+ * @returns {string | false} The link to the reference record
*/
const getResourceLinkPath = ({
- basePath,
- link = 'edit',
- linkType,
- reference,
- record = { id: '' },
resource,
source,
+ reference,
+ link = 'edit',
+ record = { id: '' },
+ basePath = `/${resource}`,
+ linkType,
}: Option): string | false => {
- const sourceId = get(record, source);
- const rootPath = basePath.replace(resource, reference);
- // Backward compatibility: keep linkType but with warning
- const getResourceLinkPath = (linkTo: LinkToType) =>
- !linkTo
- ? false
- : typeof linkTo === 'function'
- ? linkTo(record, reference)
- : linkToRecord(rootPath, sourceId, linkTo as string);
-
if (linkType !== undefined) {
console.warn(
"The 'linkType' prop is deprecated and should be named to 'link' in "
);
}
+ const sourceId = get(record, source);
+ const rootPath = basePath.replace(resource, reference);
+ const linkTo: LinkToType = linkType !== undefined ? linkType : link;
- const resourceLinkPath = getResourceLinkPath(
- linkType !== undefined ? linkType : link
- );
-
- return resourceLinkPath;
+ // Backward compatibility: keep linkType but with warning
+ return !linkTo
+ ? false
+ : typeof linkTo === 'function'
+ ? linkTo(record, reference)
+ : linkToRecord(rootPath, sourceId, linkTo as string);
};
export default getResourceLinkPath;
diff --git a/packages/ra-core/src/controller/field/useReferenceArrayFieldController.ts b/packages/ra-core/src/controller/field/useReferenceArrayFieldController.ts
index 25441498935..95d906b485f 100644
--- a/packages/ra-core/src/controller/field/useReferenceArrayFieldController.ts
+++ b/packages/ra-core/src/controller/field/useReferenceArrayFieldController.ts
@@ -14,7 +14,7 @@ import { useResourceContext } from '../../core';
import { indexById } from '../../util/indexById';
interface Option {
- basePath: string;
+ basePath?: string;
filter?: any;
page?: number;
perPage?: number;
@@ -212,7 +212,9 @@ const useReferenceArrayFieldController = (
]);
return {
- basePath: basePath.replace(resource, reference),
+ basePath: basePath
+ ? basePath.replace(resource, reference)
+ : `/${reference}`,
currentSort: sort,
data: finalData,
defaultTitle: null,
diff --git a/packages/ra-core/src/controller/field/useReferenceManyFieldController.ts b/packages/ra-core/src/controller/field/useReferenceManyFieldController.ts
index d553641da66..534552c2162 100644
--- a/packages/ra-core/src/controller/field/useReferenceManyFieldController.ts
+++ b/packages/ra-core/src/controller/field/useReferenceManyFieldController.ts
@@ -13,7 +13,7 @@ import useSortState from '../useSortState';
import { useResourceContext } from '../../core';
interface Options {
- basePath: string;
+ basePath?: string;
data?: RecordMap;
filter?: any;
ids?: any[];
@@ -186,7 +186,9 @@ const useReferenceManyFieldController = (
);
return {
- basePath: basePath.replace(resource, reference),
+ basePath: basePath
+ ? basePath.replace(resource, reference)
+ : `/${reference}`,
currentSort: sort,
data,
defaultTitle: null,
diff --git a/packages/ra-ui-materialui/src/field/ReferenceField.spec.tsx b/packages/ra-ui-materialui/src/field/ReferenceField.spec.tsx
index fa376fa993b..76e0e9e2045 100644
--- a/packages/ra-ui-materialui/src/field/ReferenceField.spec.tsx
+++ b/packages/ra-ui-materialui/src/field/ReferenceField.spec.tsx
@@ -335,5 +335,27 @@ describe('', () => {
const links = container.getElementsByTagName('a');
expect(links).toHaveLength(0);
});
+
+ it('should work without basePath', () => {
+ const { container } = render(
+
+
+
+
+
+ );
+ const links = container.getElementsByTagName('a');
+ expect(links).toHaveLength(1);
+ expect(links.item(0).href).toBe('http://localhost/posts/123');
+ });
});
});
diff --git a/packages/ra-ui-materialui/src/field/ReferenceManyField.tsx b/packages/ra-ui-materialui/src/field/ReferenceManyField.tsx
index 7cd85bcce43..3fa136b0613 100644
--- a/packages/ra-ui-materialui/src/field/ReferenceManyField.tsx
+++ b/packages/ra-ui-materialui/src/field/ReferenceManyField.tsx
@@ -170,7 +170,7 @@ export interface ReferenceManyFieldViewProps
}
ReferenceManyFieldView.propTypes = {
- basePath: PropTypes.string,
+ basePath: PropTypes.string.isRequired,
children: PropTypes.element,
className: PropTypes.string,
currentSort: PropTypes.exact({