Skip to content

Migration path: 3.x to 4.x

Jimmy Somsanith edited this page Nov 14, 2019 · 1 revision

summary

Form

Old forms use react-jsonSchema-form library from Mozilla. This lib is pulled and integrated in @talend/react-forms, even if it is not used anymore by most of the apps.

This PR deprecates the old forms and will be removed in 5.0. It can still be used partially, with extra configuration and changes in your codebase.

If you already use UIForm, everything will still work.

Include react-jsonSchema-form again

You need to set a variable process.env.FORM_MOZ = true, available during project build.

A simpler solution would be to use @talend/scripts-core (and its presets) in version 1.1.0+.
Then you can pass the variable in the npm script

{
    "scripts": {
        "start": "FORM_MOZ=true talend-scripts start",
        "build": "FORM_MOZ=true talend-scripts build",
    }
}

The imports have changed

- import Form from '@talend/react-forms/lib/Form'
+ import Form from '@talend/react-forms/lib/deprecated/Form'
-import { customWidgets } from '@talend/react-forms';
+import { customWidgets } from '@talend/react-forms/lib/deprecated';
-import { renderActionIcon } from '@talend/react-forms';
+import { renderActionIcon } from '@talend/react-forms/lib/deprecated';
-import { renderActions } from '@talend/react-forms';
+import { renderActions } from '@talend/react-forms/lib/deprecated';
-import { DataPropTypes } from '@talend/react-forms';
+import { DataPropTypes } from '@talend/react-forms/lib/deprecated';
-import { ActionsPropTypes } from '@talend/react-forms';
+import { ActionsPropTypes } from '@talend/react-forms/lib/deprecated';

Compatibility mode (props.uiform) is no longer available

Before this PR you can use previous uiSpec (uiSchema as object {} notation to extends jsonschema) and ask Form component to migrate the old uiSpec to the new one using a boolean props uiform.

This feature has been removed because it has never been usable. (lots of bug founds and way to much hard to maintain)

<Form data={{jsonSchema: {...}, uiSchema: {}} uiform />

If you do that you will now have an error message displayed.
You have 2 choices :

  • remove props.uiform, the old form will be rendered
  • migrate your schema to the UIForm schema shape

i18n

We upgraded i18next from v9 to v15 !

Make i18n available globally

There is a mode in react-i18n where it gets the i18n configuration from a global i18n configuration. To make it available when there is no context initialized, you need to set it in react-i18n and remove the i18next provider.

This is mandatory for datagrid for example that renders react components out of the main component tree. It cannot benefit the i18next provider. But if a provider is initialized in the app, it will only try to get i18n object from context, leaving the grid react components with undefined (even worse, it tries to destructure it, boom).

Edit: There is a fix to this issue in [email protected], so you can choose to keep the context, and upgrade to this version

// i18n.js
import i18n from 'i18next';
+import { initReactI18next } from 'react-i18next';

-i18n.init(...);
+i18n.use(initReactI18next).init(...);

export i18n;
// App.js
-import { I18nextProvider } from 'react-i18next';
-import i18n from './i18n';
+import './i18n'; // needed to init the i18next configuration
import App from './App';

-<I18nextProvider i18n={i18n}>
  <App />
-</I18nextProvider>

Don't use the hoc getTranslated

The getTranslated HOC decorates your component with one i18n provider. Now, The i18n provider is provided by your i18n config.

-import getTranslated from '@talend/react-components/lib/TranslateWrapper';

-	.directive('pureAppHeaderBar', ['reactDirective', reactDirective => reactDirective(
-		getTranslated(AppHeaderBar, { i18n })
-	)])
+       .directive('pureAppHeaderBar', ['reactDirective', reactDirective => reactDirective(AppHeaderBar)]);

Import change

HOC translate has been renamed withI18nTranslate.

There is a codemod to change translate() import and usage

npx jscodeshift -t <talend_ui_path>/codemodes/i18next/from_9_to_15.js <your_app_src>

HOC display name

HOC display name has changed from Translate(myComp) to withI18nextTranslation(MyComp).
You will likely need to update your tests

  • snapshots: displayName has changed and inserted component has been removed from component tree.
  • selectors: if you selected Translate(MyComponent) you now need to select withI18nextTranslation(MyComponent)
  • If you attach sub components to your main components (like List.Item for example) you need to pay attention to how you export them:

https://react.i18next.com/latest/withtranslation-hoc#hoist-non-react-statics

// Wrong, this will result in having to import `MyComponent.WrappedComponent.Item`
MyComponent.Item = SomeOtherComponent;
export default withTranslation()(MyComponent);

// Correct, here you can import `MyComponent.Item`
const TranslatedMyComponent = withTranslation()(MyComponent);
TranslatedMyComponent.Item = SomeOtherComponent;
export default TranslatedMyComponent;

Breadcrumb

UX guideline has been update, instead of having an ellipsis at the beginning of the breadcrumb, it is after the first element.

Before we used maxItems to specify how many items should be always displayed after the ellipsis button.

maxItems example
2 Home / Folder 1
2 … / Folder 1 / Folder 2
3 Home / Folder 1 / Folder 2
3 … / Folder 2 / Folder 3 / Folder 4

Now, root item is always visible, so we use maxItems to specify how many items should be displayed including root and the ellipsis button

maxItems example
3 Home / Folder 1 / Folder 2
3 Home / … / Folder 3
4 Home / … / Folder 3 / Folder 4
4 Home / … / Folder 4 / Folder 5

So if you used

<Breadcrumb maxItems='2'  />

you must consider changing it to

<Breadcrumb maxItems='4'  />