Skip to content

Commit

Permalink
Merge pull request #7641 from marmelab/fix-simple-form-iterator-labels
Browse files Browse the repository at this point in the history
Fix SimpleFormIterator Labels
  • Loading branch information
fzaninotto authored May 5, 2022
2 parents dc6bce6 + 5496c72 commit a6dd50c
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 32 deletions.
15 changes: 13 additions & 2 deletions packages/ra-core/src/util/getFieldLabelTranslationArgs.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,22 @@ describe('getFieldLabelTranslationArgs', () => {
]);
});

it('should return the source and resource as translate key', () =>
it('should return the source and resource as translate key', () => {
expect(
getFieldLabelTranslationArgs({
resource: 'posts',
source: 'title',
})
).toEqual([`resources.posts.fields.title`, { _: 'Title' }]));
).toEqual([`resources.posts.fields.title`, { _: 'Title' }]);
});

it('should accept use the parentSource to build the translation key if provided', () => {
expect(
getFieldLabelTranslationArgs({
resource: 'posts',
source: 'url',
parentSource: 'backlinks',
})
).toEqual([`resources.posts.fields.backlinks.url`, { _: 'Url' }]);
});
});
8 changes: 5 additions & 3 deletions packages/ra-core/src/util/getFieldLabelTranslationArgs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import inflection from 'inflection';

interface Args {
label?: string;
parentSource?: string;
resource?: string;
source?: string;
}
Expand All @@ -22,13 +23,14 @@ export default (options?: Args): TranslationArguments => {
return [''];
}

const { label, resource, source } = options;

const { label, parentSource, resource, source } = options;
return typeof label !== 'undefined'
? [label, { _: label }]
: typeof source !== 'undefined'
? [
`resources.${resource}.fields.${source}`,
`resources.${resource}.fields.${
parentSource ? `${parentSource}.${source}` : source
}`,
{
_: inflection.transform(source, ['underscore', 'humanize']),
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,19 +116,19 @@ describe('<ArrayInput />', () => {
</AdminContext>
);
expect(
screen.queryAllByLabelText('resources.bar.fields.id')
screen.queryAllByLabelText('resources.bar.fields.arr.id')
).toHaveLength(2);
expect(
screen
.queryAllByLabelText('resources.bar.fields.id')
.queryAllByLabelText('resources.bar.fields.arr.id')
.map(input => (input as HTMLInputElement).value)
).toEqual(['123', '456']);
expect(
screen.queryAllByLabelText('resources.bar.fields.foo')
screen.queryAllByLabelText('resources.bar.fields.arr.foo')
).toHaveLength(2);
expect(
screen
.queryAllByLabelText('resources.bar.fields.foo')
.queryAllByLabelText('resources.bar.fields.arr.foo')
.map(input => (input as HTMLInputElement).value)
).toEqual(['bar', 'baz']);
});
Expand Down Expand Up @@ -169,7 +169,7 @@ describe('<ArrayInput />', () => {
});
fireEvent.click(screen.getByText('ra.action.add'));
const firstId = screen.getAllByLabelText(
'resources.bar.fields.id *'
'resources.bar.fields.arr.id *'
)[0];
fireEvent.change(firstId, {
target: { value: 'aaa' },
Expand All @@ -179,7 +179,7 @@ describe('<ArrayInput />', () => {
});
fireEvent.blur(firstId);
const firstFoo = screen.getAllByLabelText(
'resources.bar.fields.foo *'
'resources.bar.fields.arr.foo *'
)[0];
fireEvent.change(firstFoo, {
target: { value: 'aaa' },
Expand All @@ -195,7 +195,7 @@ describe('<ArrayInput />', () => {
});
});

it('should mantain its form value after having been unmounted', async () => {
it('should maintain its form value after having been unmounted', async () => {
let value, setArrayInputVisible;

const MyArrayInput = () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ describe('<SimpleFormIterator />', () => {
</Wrapper>
);
const inputElements = screen.queryAllByLabelText(
'resources.undefined.fields.email'
'resources.undefined.fields.emails.email'
);
expect(inputElements).toHaveLength(2);
expect((inputElements[0] as HTMLInputElement).disabled).toBeFalsy();
Expand All @@ -75,7 +75,7 @@ describe('<SimpleFormIterator />', () => {
</Wrapper>
);
const inputElements = screen.queryAllByLabelText(
'resources.undefined.fields.email'
'resources.undefined.fields.emails.email'
);
expect(inputElements).toHaveLength(2);
expect((inputElements[0] as HTMLInputElement).disabled).toBeTruthy();
Expand All @@ -102,7 +102,7 @@ describe('<SimpleFormIterator />', () => {
</Wrapper>
);
const inputElements = screen.queryAllByLabelText(
'resources.undefined.fields.email'
'resources.undefined.fields.emails.email'
);
expect(inputElements).toHaveLength(2);
expect((inputElements[0] as HTMLInputElement).disabled).toBeTruthy();
Expand Down Expand Up @@ -221,7 +221,7 @@ describe('<SimpleFormIterator />', () => {
fireEvent.click(addItemElement);
await waitFor(() => {
const inputElements = screen.queryAllByLabelText(
'resources.undefined.fields.email'
'resources.undefined.fields.emails.email'
);

expect(inputElements.length).toBe(1);
Expand All @@ -230,14 +230,14 @@ describe('<SimpleFormIterator />', () => {
fireEvent.click(addItemElement);
await waitFor(() => {
const inputElements = screen.queryAllByLabelText(
'resources.undefined.fields.email'
'resources.undefined.fields.emails.email'
);

expect(inputElements.length).toBe(2);
});

const inputElements = screen.queryAllByLabelText(
'resources.undefined.fields.email'
'resources.undefined.fields.emails.email'
) as HTMLInputElement[];

expect(
Expand Down Expand Up @@ -339,7 +339,7 @@ describe('<SimpleFormIterator />', () => {
);

const inputElements = screen.queryAllByLabelText(
'resources.undefined.fields.email'
'resources.undefined.fields.emails.email'
) as HTMLInputElement[];

expect(
Expand All @@ -356,7 +356,7 @@ describe('<SimpleFormIterator />', () => {
fireEvent.click(removeFirstButton);
await waitFor(() => {
const inputElements = screen.queryAllByLabelText(
'resources.undefined.fields.email'
'resources.undefined.fields.emails.email'
) as HTMLInputElement[];

expect(
Expand All @@ -383,7 +383,7 @@ describe('<SimpleFormIterator />', () => {
);

const inputElements = screen.queryAllByLabelText(
'resources.undefined.fields.email'
'resources.undefined.fields.emails.email'
) as HTMLInputElement[];

expect(
Expand All @@ -399,7 +399,7 @@ describe('<SimpleFormIterator />', () => {
fireEvent.click(moveDownFirstButton[0]);
await waitFor(() => {
const inputElements = screen.queryAllByLabelText(
'resources.undefined.fields.email'
'resources.undefined.fields.emails.email'
) as HTMLInputElement[];

expect(
Expand All @@ -414,7 +414,7 @@ describe('<SimpleFormIterator />', () => {
fireEvent.click(moveUpButton[1]);
await waitFor(() => {
const inputElements = screen.queryAllByLabelText(
'resources.undefined.fields.email'
'resources.undefined.fields.emails.email'
) as HTMLInputElement[];

expect(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,9 @@ export const SimpleFormIterator = (props: SimpleFormIteratorProps) => {
add: addField,
remove: removeField,
reOrder: handleReorder,
source,
}),
[fields.length, addField, removeField, handleReorder]
[addField, fields.length, handleReorder, removeField, source]
);
return fields ? (
<SimpleFormIteratorContext.Provider value={context}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ export const SimpleFormIteratorContext = createContext<
>(undefined);

export type SimpleFormIteratorContextValue = {
total: number;
add: () => void;
remove: (index: number) => void;
reOrder: (index: number, newIndex: number) => void;
source: string;
total: number;
};
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
} from 'react';
import { Typography } from '@mui/material';
import clsx from 'clsx';
import { RaRecord } from 'ra-core';
import { getFieldLabelTranslationArgs, RaRecord, useTranslate } from 'ra-core';

import { SimpleFormIteratorClasses } from './useSimpleFormIteratorStyles';
import { useSimpleFormIterator } from './useSimpleFormIterator';
Expand All @@ -38,7 +38,13 @@ export const SimpleFormIteratorItem = React.forwardRef(
source,
} = props;

const { total, reOrder, remove } = useSimpleFormIterator();
const translate = useTranslate();
const {
total,
reOrder,
remove,
source: parentSource,
} = useSimpleFormIterator();
// Returns a boolean to indicate whether to disable the remove button for certain fields.
// If disableRemove is a function, then call the function with the current record to
// determining if the button should be disabled. Otherwise, use a boolean property that
Expand Down Expand Up @@ -111,11 +117,21 @@ export const SimpleFormIteratorItem = React.forwardRef(
: member,
index: source ? undefined : index2,
label:
typeof input.props.label === 'undefined'
? source
? `resources.${resource}.fields.${source}`
: undefined
: input.props.label,
input.props.label === '' ||
input.props.label === false
? input.props.label
: // We can't rely on the default label inference done in the input by FieldTitle because
// at the time it renders, its source will be something like `arraySource.0.inputSource`
// and inference will fail
translate(
...getFieldLabelTranslationArgs(
{
parentSource,
resource,
source,
}
)
),
disabled,
...inputProps,
});
Expand Down

0 comments on commit a6dd50c

Please sign in to comment.