react-admin
react-admin copied to clipboard
Auto translate resource fields does not work when using an add/edit form inside a Dialog
I have two ways to edit an alarm, one via a dedicated list with default create/edit forms, and one via a list inside the tab of a related parent record.
The fields in the default create/edit forms are translated properly, but not in the form inside the Dialog.
I have added a short video to demonstrate what I mean. https://user-images.githubusercontent.com/3696955/120433238-4884f980-c37b-11eb-81af-ea5db4d4c50f.mp4
Edit: Saving form when hitting enter inside a TextField does not work as well, possibly related? /Edit
I am using:
- "react-dom": "17.0.2"
- "react": "17.0.2"
- "react-admin": "3.15.2"
- "ra-i18n-polyglot": "3.15.2"
The code for the "Alarms" tab:
import {
Button, Datagrid, ExportButton, FormWithRedirect, List, required, SaveButton, TextField, TextInput, TopToolbar,
TranslatableFields, useCreate, useListContext, useNotify, useRefresh,
} from "react-admin";
import {useState} from "react";
import AddIcon from "@material-ui/icons/Add";
import {Dialog, DialogActions, DialogContent, DialogTitle} from "@material-ui/core";
import IconCancel from "@material-ui/icons/Cancel";
import locales from "../../../locales.js";
const AddAlarmDialog = ({machineTypeId, open = false, onClose, onSuccess}) => {
const [create, { loading }] = useCreate('machine-files');
const notify = useNotify();
const handleSubmit = async values => {
create(
{
payload: {
data: {
...values,
machineTypeId: machineTypeId
}
}
},
{
onSuccess: () => {
onSuccess();
},
onFailure: (error) => {
notify(error.message, 'error');
}
}
);
};
return (
<Dialog
open={open}
onClose={onClose}
fullWidth
maxWidth="md"
>
<DialogTitle>Alarm toevoegen</DialogTitle>
<FormWithRedirect
resource="machine-alarms"
save={handleSubmit}
render={({
handleSubmitWithRedirect,
pristine,
saving
}) => (
<>
<DialogContent>
<TextInput
source="code"
validate={[required()]}
/>
<TranslatableFields locales={locales}>
<TextInput multiline fullWidth source="cause" />
<TextInput multiline fullWidth source="description" />
<TextInput multiline fullWidth source="solution" />
</TranslatableFields>
</DialogContent>
<DialogActions>
<Button
label="ra.action.cancel"
onClick={onClose}
disabled={loading}
>
<IconCancel />
</Button>
<SaveButton
handleSubmitWithRedirect={
handleSubmitWithRedirect
}
pristine={pristine}
saving={saving}
disabled={loading}
/>
</DialogActions>
</>
)}
/>
</Dialog>
)
}
const ListActions = ({props, machineTypeId}) => {
const [showAddAlarmDialog, setShowAlarmDialog] = useState(false);
const refresh = useRefresh();
const {
maxResults,
} = props;
const {
currentSort,
resource,
filterValues,
total,
} = useListContext();
return (
<>
<TopToolbar>
<Button
size="small"
label="Toevoegen"
onClick={() => {
setShowAlarmDialog(true);
}}
>
<AddIcon />
</Button>
<ExportButton
disabled={total === 0}
resource={resource}
sort={currentSort}
filterValues={filterValues}
maxResults={maxResults}
/>
</TopToolbar>
<AddAlarmDialog
props={props}
open={showAddAlarmDialog}
onClose={() => {
setShowAlarmDialog(false);
}}
onSuccess={() => {
setShowAlarmDialog(false);
refresh(); // todo refresh only alarm list and not everything
}}
machineTypeId={machineTypeId}
/>
</>
)
}
const TabAlarms = ({props, machineTypeId}) => {
return (
<List
{...props}
style={{
width: '100%'
}}
resource="machine-alarms"
filter={{
machineTypeId: machineTypeId
}}
perPage={25}
title=" "
actions={<ListActions
props={props}
machineTypeId={props.id}
/>}
empty={false}
>
<Datagrid>
<TextField
source="id"
/>
<TextField
source="cause.nl"
/>
<TextField
source="description.nl"
/>
<TextField
source="solution.nl"
/>
</Datagrid>
</List>
)
}
export default TabAlarms;
Thanks for reporting this. Please provide a sample application showing the issue by forking the following CodeSandbox (https://codesandbox.io/s/github/marmelab/react-admin/tree/master/examples/simple).
Translation also fails when I am using an Input inside a FormDataConsumer
For example:
<FormDataConsumer>
{({ formData, ...rest }) => (
<>
{formData.userTypeId === 2 &&
<BooleanInput
source="receivesSystemEmails"
helperText="resources.users.fieldHelperTexts.receivesSystemEmails" // <<<<<<<< fails here
/>
}
</>
)}
</FormDataConsumer>
<BooleanInput
source="receivesSystemEmails"
helperText="resources.users.fieldHelperTexts.receivesSystemEmails" // <<<<<<<<< works here
/>
@djhi Also I am using the Enterprice edition, could you please fix this as soon as possible?
Hi Lucus,
I can't reproduce the problem you describe (failed translation inside a FormDataConsumer) with the simple example (see https://codesandbox.io/s/inspiring-bartik-1u4h9?file=/src/posts/PostEdit.tsx). There must be something else in your code that causes the bug. It may be caused by a duplicate ra-core or ra-ui-material-ui package in your yarn.lock.
Can you please try and reproduce your issue based on the URL above?
Cheers,
François
Having the same issue when I use an custom Edit form made with those instructions:
https://github.com/marmelab/react-admin/blob/e1ad7e6485b39a341d4d45e93b489fde5f333eea/docs/CreateEdit.md#usecreatecontroller
The translations worked fine in the old style Edit form.
I have no experience with typescript nor with codesandbox.
If you can provide me a sandbox based on JavaScript I can try to reproduce the problem there.
Some additional info:
package.json:
{
"name": "test",
"version": "0.1.0",
"private": true,
"dependencies": {
"@date-io/date-fns": "1.3.13",
"@material-ui/core": "4.12.3",
"@material-ui/data-grid": "4.0.0-alpha.31",
"@material-ui/icons": "4.11.2",
"@material-ui/pickers": "3.3.10",
"@material-ui/styles": "4.11.4",
"@react-admin/ra-navigation": "2.3.5",
"@react-admin/ra-preferences": "1.4.0",
"@testing-library/jest-dom": "5.12.0",
"@testing-library/react": "11.2.6",
"@testing-library/user-event": "12.8.3",
"base-64": "1.0.0",
"chart.js": "3.5.1",
"chokidar": "3.5.2",
"date-fns": "2.22.1",
"iframe-resizer": "4.3.2",
"inflection": "1.13.1",
"js-file-downloader": "1.1.19",
"jwt-decode": "3.1.2",
"lodash": "4.17.21",
"luxon": "2.0.2",
"nice-bytes": "1.1.0",
"papaparse": "5.3.1",
"ra-data-simple-rest": "3.13.4",
"ra-i18n-polyglot": "3.18.3",
"ra-language-dutch": "3.17.2",
"ra-language-english": "3.18.3",
"react": "17.0.2",
"react-admin": "3.18.3",
"react-admin-import-csv": "1.0.19",
"react-chartjs-2": "3.0.4",
"react-dom": "17.0.2",
"react-dropzone": "11.3.2",
"react-final-form": "6.5.3",
"react-final-form-listeners": "1.0.3",
"react-icons": "4.3.1",
"react-markdown": "6.0.2",
"react-router-dom": "5.3.0",
"react-scripts": "4.0.3",
"remark-gfm": "1.0.0",
"throttle-debounce": "3.0.1",
"web-vitals": "1.1.2"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
App.js:
import {fetchUtils, Resource} from "react-admin";
import simpleRestProvider from 'ra-data-simple-rest'; // cheers guys! <3
import {Admin} from 'react-admin';
import layout from "./layout/index.js";
import {MuiPickersUtilsProvider} from '@material-ui/pickers';
import DateFnsUtils from '@date-io/date-fns';
import {ShowAppVersionInfoDialogContextProvider} from "./contexts/show-app-version-info-dialog";
import {authProvider} from "./auth/provider";
import {Dashboard} from "./dashboard";
import customRoutes from "./custom-routes/index";
import dutchMessages from 'ra-language-dutch';
import englishMessages from 'ra-language-english';
import polyglotI18nProvider from 'ra-i18n-polyglot';
import nlLocale from "date-fns/locale/nl";
import dutchTranslations from "./i18n/nl";
import englishTranslations from "./i18n/en";
const httpClient = (url, options = {}) => {
if (!options.headers) {
options.headers = new Headers({ Accept: 'application/json' });
}
if (localStorage.getItem("apiAccessToken") !== null) {
options.headers.set('Authorization', `Bearer ${localStorage.getItem("apiAccessToken")}`);
}
return fetchUtils.fetchJson(url, options);
};
const dataProvider = simpleRestProvider(process.env.REACT_APP_DATA_BASE_URL + '/admin-api/simple-rest', httpClient);
const messages = {
'nl': {...dutchMessages, ...dutchTranslations},
'en': {...englishMessages, ...englishTranslations},
};
const i18nProvider = polyglotI18nProvider((locale) => {
return messages[locale];
}, 'nl');
const App = () => {
return (
<>
<MuiPickersUtilsProvider
utils={DateFnsUtils}
locale={nlLocale}
>
<ShowAppVersionInfoDialogContextProvider>
<Admin
i18nProvider={i18nProvider}
dataProvider={dataProvider}
authProvider={authProvider}
dashboard={Dashboard}
layout={layout}
// loginPage={Login}
customRoutes={customRoutes}
//theme={theme}
title="Kletec Admin panel"
>
...
</Admin>
</ShowAppVersionInfoDialogContextProvider>
</MuiPickersUtilsProvider>
</>
)
};
export default App;
@fzaninotto @djhi can you please take another look at this?
With the release of react-admin v5, react-admin v3 has reached its end of life. We won't fix bugs or make any new release on the 3.x branch. We recommend that you switch to a more recent version of react-admin.
So I'm closing this issue as we won't fix it.