From 196f65bc42a7460592959a57c312c654c90bd69f Mon Sep 17 00:00:00 2001 From: Florian Gareis Date: Tue, 25 Jan 2022 21:24:43 +0100 Subject: [PATCH 1/2] Fix useMemo() for translation objects --- packages/react/src/JsonFormsContext.tsx | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/packages/react/src/JsonFormsContext.tsx b/packages/react/src/JsonFormsContext.tsx index cbb911533..601f189a7 100644 --- a/packages/react/src/JsonFormsContext.tsx +++ b/packages/react/src/JsonFormsContext.tsx @@ -225,7 +225,7 @@ export const ctxToEnumControlProps = (ctx: JsonFormsStateContext, props: OwnProp * Make sure, that options are memoized as otherwise the component will rerender for every change, * as the options array is recreated every time. */ - const options = useMemo(() => enumProps.options, [props.options, enumProps.schema]); + const options = useMemo(() => enumProps.options, [props.options, enumProps.schema, ctx.i18n?.translate]); return {...enumProps, options} } @@ -235,12 +235,19 @@ export const ctxToOneOfEnumControlProps = (ctx: JsonFormsStateContext, props: Ow * Make sure, that options are memoized as otherwise the component will rerender for every change, * as the options array is recreated every time. */ - const options = useMemo(() => enumProps.options, [props.options, enumProps.schema]); + const options = useMemo(() => enumProps.options, [props.options, enumProps.schema, ctx.i18n?.translate]); return {...enumProps, options} } -export const ctxToMultiEnumControlProps = (ctx: JsonFormsStateContext, props: OwnPropsOfControl) => - mapStateToMultiEnumControlProps({ jsonforms: { ...ctx } }, props); +export const ctxToMultiEnumControlProps = (ctx: JsonFormsStateContext, props: OwnPropsOfControl) => { + const enumProps = mapStateToMultiEnumControlProps({ jsonforms: { ...ctx } }, props); + /** + * Make sure, that options are memoized as otherwise the component will rerender for every change, + * as the options array is recreated every time. + */ + const options = useMemo(() => enumProps.options, [enumProps.schema, ctx.i18n?.translate]); + return {...enumProps, options} +} export const ctxToControlWithDetailProps = ( ctx: JsonFormsStateContext, @@ -318,7 +325,7 @@ export const ctxToEnumCellProps = ( * Make sure, that options are memoized as otherwise the cell will rerender for every change, * as the options array is recreated every time. */ - const options = useMemo(() => cellProps.options, [ownProps.options, cellProps.schema]); + const options = useMemo(() => cellProps.options, [ownProps.options, cellProps.schema, ctx.i18n?.translate]); return {...cellProps, options} }; @@ -331,7 +338,7 @@ export const ctxToOneOfEnumCellProps = ( * Make sure, that options are memoized as otherwise the cell will rerender for every change, * as the options array is recreated every time. */ - const options = useMemo(() => enumCellProps.options, [props.options, enumCellProps.schema]) + const options = useMemo(() => enumCellProps.options, [props.options, enumCellProps.schema, ctx.i18n?.translate]) return {...enumCellProps, options}; }; From b1ed4873b759a3a90950c291e046f58ad91bf1c8 Mon Sep 17 00:00:00 2001 From: Stefan Dirix Date: Thu, 3 Feb 2022 14:51:35 +0100 Subject: [PATCH 2/2] Add test cases --- .../renderers/MaterialEnumControl.test.tsx | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 packages/material/test/renderers/MaterialEnumControl.test.tsx diff --git a/packages/material/test/renderers/MaterialEnumControl.test.tsx b/packages/material/test/renderers/MaterialEnumControl.test.tsx new file mode 100644 index 000000000..0908ce498 --- /dev/null +++ b/packages/material/test/renderers/MaterialEnumControl.test.tsx @@ -0,0 +1,75 @@ +/* + The MIT License + + Copyright (c) 2017-2019 EclipseSource Munich + https://github.com/eclipsesource/jsonforms + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ +import './MatchMediaMock'; +import * as React from 'react'; +import { + ControlElement +} from '@jsonforms/core'; +import { materialRenderers, MuiSelect } from '../../src'; + +import Enzyme, { mount } from 'enzyme'; +import Adapter from '@wojtekmaj/enzyme-adapter-react-17'; +import { JsonFormsStateProvider } from '@jsonforms/react'; +import { initCore } from './util'; +import { MaterialEnumControl } from '../../src'; + +Enzyme.configure({ adapter: new Adapter() }); + +const data = { nationality: 'JP' }; +const schema = { + type: 'string', + enum: ['DE', 'IT', 'JP', 'US', 'RU', 'Other'] +}; +const uischema: ControlElement = { + type: 'Control', + scope: '#/properties/nationality', + options: { + autocomplete: false + } +}; + +describe('Material enum control', () => { + it('enum options should change when translation changes', () => { + const core = initCore(schema, uischema, data); + const translate = () => 'Translated'; + const changedTranslate = () => 'OtherTranslation'; + const wrapper = mount( + + + + ); + + expect(wrapper.find(MuiSelect).props().options[0].label).toBe('Translated'); + + wrapper.setProps({ initState: { renderers: materialRenderers, core, i18n: {translate: changedTranslate} }} ); + wrapper.update(); + + expect(wrapper.find(MuiSelect).props().options[0].label).toBe('OtherTranslation'); + }); +});