Skip to content

Commit

Permalink
Replace LabelPrefix with SourceContext
Browse files Browse the repository at this point in the history
  • Loading branch information
djhi committed Jan 9, 2024
1 parent de6e019 commit 1a7b3b9
Show file tree
Hide file tree
Showing 12 changed files with 86 additions and 70 deletions.
11 changes: 7 additions & 4 deletions packages/ra-core/src/form/Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ import {
OptionalRecordContextProvider,
SaveHandler,
} from '../controller';
import { useResourceContext } from '../core';
import { LabelPrefixContextProvider } from '../util';
import { SourceContextProvider, SourceContextValue, useResourceContext } from '../core';
import { ValidateForm } from './getSimpleValidationResolver';
import { useAugmentedForm } from './useAugmentedForm';

Expand Down Expand Up @@ -53,10 +52,14 @@ export const Form = <RecordType = any>(props: FormProps<RecordType>) => {
const record = useRecordContext(props);
const resource = useResourceContext(props);
const { form, formHandleSubmit } = useAugmentedForm(props);
const sourceContext = React.useMemo<SourceContextValue>(() => ({
getSource: (source: string) => source,
getLabel: (source: string) => `resources.${resource}.fields.${source}`,
}), [resource]);

return (
<OptionalRecordContextProvider value={record}>
<LabelPrefixContextProvider prefix={`resources.${resource}.fields`}>
<SourceContextProvider value={sourceContext}>
<FormProvider {...form}>
<FormGroupsProvider>
<form
Expand All @@ -69,7 +72,7 @@ export const Form = <RecordType = any>(props: FormProps<RecordType>) => {
</form>
</FormGroupsProvider>
</FormProvider>
</LabelPrefixContextProvider>
</SourceContextProvider>
</OptionalRecordContextProvider>
);
};
Expand Down
24 changes: 23 additions & 1 deletion packages/ra-core/src/i18n/useTranslateLabel.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -146,10 +146,32 @@ describe('useTranslateLabel', () => {
getLabel: source => `test.${source}`,
}}
>
<TranslateLabel source="title" resource="posts" />
<TranslateLabel source="title" />
</SourceContextProvider>
</TestTranslationProvider>
);
screen.getByText('Label for title');
});

it('should return the inferred label when a resource prop is provided even when a SourceContext is present', () => {
render(
<TestTranslationProvider
messages={{
test: {
title: 'Label for title',
},
}}
>
<SourceContextProvider
value={{
getSource: source => source,
getLabel: source => `test.${source}`,
}}
>
<TranslateLabel source="title" resource="posts" />
</SourceContextProvider>
</TestTranslationProvider>
);
screen.getByText('Title');
});
});
6 changes: 2 additions & 4 deletions packages/ra-core/src/i18n/useTranslateLabel.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { useCallback, ReactElement } from 'react';

import { useTranslate } from './useTranslate';
import { useLabelPrefix, getFieldLabelTranslationArgs } from '../util';
import { getFieldLabelTranslationArgs } from '../util';
import { useResourceContext, useSourceContext } from '../core';

export const useTranslateLabel = () => {
const translate = useTranslate();
const prefix = useLabelPrefix();
const resourceFromContext = useResourceContext();
const sourceContext = useSourceContext();

Expand Down Expand Up @@ -34,13 +33,12 @@ export const useTranslateLabel = () => {
...getFieldLabelTranslationArgs({
label: label as string,
defaultLabel: sourceContext?.getLabel(source),
prefix,
resource,
resourceFromContext,
source: finalSource,
})
);
},
[prefix, resourceFromContext, translate, sourceContext]
[resourceFromContext, translate, sourceContext]
);
};
3 changes: 0 additions & 3 deletions packages/ra-core/src/util/LabelPrefixContext.ts

This file was deleted.

18 changes: 0 additions & 18 deletions packages/ra-core/src/util/LabelPrefixContextProvider.tsx

This file was deleted.

10 changes: 5 additions & 5 deletions packages/ra-core/src/util/getFieldLabelTranslationArgs.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,17 +80,17 @@ describe('getFieldLabelTranslationArgs', () => {
getFieldLabelTranslationArgs({
resource: 'posts',
resourceFromContext: 'users',
prefix: 'resources.users.fields',
defaultLabel: 'resources.users.fields.name',
source: 'referenceOne.users@@name',
})
).toEqual(['resources.users.fields.name', { _: 'Name' }]);
});

it('should prefer the resource over the prefix', () => {
it('should prefer the resource over the defaultLabel', () => {
expect(
getFieldLabelTranslationArgs({
resource: 'books',
prefix: 'resources.posts.fields',
defaultLabel: 'resources.posts.fields.title',
source: 'title',
})
).toEqual([`resources.books.fields.title`, { _: 'Title' }]);
Expand All @@ -106,10 +106,10 @@ describe('getFieldLabelTranslationArgs', () => {
).toEqual([`resources.posts.fields.title`, { _: 'Title' }]);
});

it('should prefer the prefix over the resourceFromContext', () => {
it('should prefer the defaultLabel over the resourceFromContext', () => {
expect(
getFieldLabelTranslationArgs({
prefix: 'resources.posts.fields',
defaultLabel: 'resources.posts.fields.title',
resourceFromContext: 'books',
source: 'title',
})
Expand Down
26 changes: 12 additions & 14 deletions packages/ra-core/src/util/getFieldLabelTranslationArgs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import inflection from 'inflection';
interface Args {
label?: string;
defaultLabel?: string;
prefix?: string;
resource?: string;
resourceFromContext?: string;
source?: string;
Expand All @@ -22,13 +21,14 @@ type TranslationArguments = [string, any?];
*
* @see useTranslateLabel for a ready-to-use hook
*/
export default (options?: Args): TranslationArguments => {
export const getFieldLabelTranslationArgs = (
options?: Args
): TranslationArguments => {
if (!options) return [''];

const {
label,
defaultLabel,
prefix,
resource,
resourceFromContext,
source,
Expand All @@ -45,30 +45,28 @@ export default (options?: Args): TranslationArguments => {
['underscore', 'humanize']
);

if (defaultLabel) {
return [defaultLabel, { _: defaultLabelTranslation }];
}

if (resource) {
return [
`resources.${resource}.fields.${sourceWithoutDigits}`,
getResourceFieldLabelKey(resource, sourceWithoutDigits),
{ _: defaultLabelTranslation },
];
}

if (prefix) {
return [
`${prefix}.${sourceWithoutDigits}`,
{ _: defaultLabelTranslation },
];
if (defaultLabel) {
return [defaultLabel, { _: defaultLabelTranslation }];
}

return [
`resources.${resourceFromContext}.fields.${sourceWithoutDigits}`,
getResourceFieldLabelKey(resourceFromContext, sourceWithoutDigits),
{ _: defaultLabelTranslation },
];
};

export default getFieldLabelTranslationArgs;

export const getResourceFieldLabelKey = (resource: string, source: string) =>
`resources.${resource}.fields.${source}`;

/**
* Uses the source string to guess a translation message and a default label.
*
Expand Down
6 changes: 1 addition & 5 deletions packages/ra-core/src/util/index.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
import escapePath from './escapePath';
import FieldTitle, { FieldTitleProps } from './FieldTitle';
import getFieldLabelTranslationArgs from './getFieldLabelTranslationArgs';
import ComponentPropType from './ComponentPropType';
import removeEmpty from './removeEmpty';
import removeKey from './removeKey';
import Ready from './Ready';
import warning from './warning';
import useWhyDidYouUpdate from './useWhyDidYouUpdate';
import { getMutationMode } from './getMutationMode';
export * from './getFieldLabelTranslationArgs';
export * from './mergeRefs';
export * from './useEvent';

export {
escapePath,
FieldTitle,
getFieldLabelTranslationArgs,
ComponentPropType,
Ready,
removeEmpty,
Expand All @@ -28,7 +27,4 @@ export type { FieldTitleProps };
export * from './asyncDebounce';
export * from './hooks';
export * from './shallowEqual';
export * from './LabelPrefixContext';
export * from './LabelPrefixContextProvider';
export * from './useLabelPrefix';
export * from './useCheckForApplicationUpdate';
4 changes: 0 additions & 4 deletions packages/ra-core/src/util/useLabelPrefix.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,13 @@ import {
} from 'react';
import { Typography } from '@mui/material';
import clsx from 'clsx';
import { RaRecord, SourceContextProvider, useResourceContext } from 'ra-core';
import {
getResourceFieldLabelKey,
RaRecord,
SourceContextProvider,
useResourceContext,
useSourceContext,
} from 'ra-core';

import { SimpleFormIteratorClasses } from './useSimpleFormIteratorStyles';
import { useSimpleFormIterator } from './useSimpleFormIterator';
Expand Down Expand Up @@ -74,19 +80,23 @@ export const SimpleFormIteratorItem = React.forwardRef(
? getItemLabel(index)
: getItemLabel;

const parentSourceContext = useSourceContext();
const sourceContext = useMemo(
() => ({
getSource: (source: string) =>
source ? `${member}.${source}` : member,
getLabel: (source: string) => {
// remove digits, e.g. 'book.authors.2.categories.3.identifier.name' => 'book.authors.categories.identifier.name'
return `resources.${resource}.fields.${member.replace(
const itemSource = `${member.replace(
/\.\d+/g,
''
)}.${source}`;
return parentSourceContext
? parentSourceContext.getLabel(itemSource)
: getResourceFieldLabelKey(resource, itemSource);
},
}),
[member, resource]
[member, parentSourceContext, resource]
);

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ import {
FormGroupContextProvider,
RaRecord,
SourceContextProvider,
getResourceFieldLabelKey,
useResourceContext,
useSourceContext,
useTranslatableContext,
} from 'ra-core';

Expand All @@ -21,16 +23,18 @@ export const TranslatableInputsTabContent = (
const { children, groupKey = '', locale, ...other } = props;
const resource = useResourceContext(props);
const { selectedLocale } = useTranslatableContext();
const parentSourceContext = useSourceContext();
const sourceContext = useMemo(
() => ({
getSource: (source: string) => `${source}.${locale}`,
getLabel: (source: string) =>
`resources.${resource}.fields.${source.replace(
`.${locale}`,
''
)}`,
getLabel: (source: string) => {
const itemSource = source.replace(`.${locale}`, '');
return parentSourceContext
? parentSourceContext.getLabel(itemSource)
: getResourceFieldLabelKey(resource, itemSource);
},
}),
[locale, resource]
[locale, parentSourceContext, resource]
);

return (
Expand Down
16 changes: 13 additions & 3 deletions packages/ra-ui-materialui/src/list/filter/FilterForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ import {
import PropTypes from 'prop-types';
import { styled } from '@mui/material/styles';
import {
LabelPrefixContextProvider,
ListFilterContextValue,
SourceContextProvider,
SourceContextValue,
useListContext,
useResourceContext,
} from 'ra-core';
Expand Down Expand Up @@ -130,8 +131,17 @@ export const FilterFormBase = (props: FilterFormBaseProps) => {
[hideFilter]
);

const sourceContext = React.useMemo<SourceContextValue>(
() => ({
getSource: (source: string) => source,
getLabel: (source: string) =>
`resources.${resource}.fields.${source}`,
}),
[resource]
);

return (
<LabelPrefixContextProvider prefix={`resources.${resource}.fields`}>
<SourceContextProvider value={sourceContext}>
<StyledForm
className={className}
{...sanitizeRestProps(rest)}
Expand All @@ -148,7 +158,7 @@ export const FilterFormBase = (props: FilterFormBaseProps) => {
))}
<div className={FilterFormClasses.clearFix} />
</StyledForm>
</LabelPrefixContextProvider>
</SourceContextProvider>
);
};

Expand Down

0 comments on commit 1a7b3b9

Please sign in to comment.