From 8cdd5ef695886550442741331bf85b83dd5a27c0 Mon Sep 17 00:00:00 2001 From: LukasBoll Date: Fri, 13 Sep 2024 18:16:59 +0200 Subject: [PATCH] =?UTF-8?q?=EF=BB=BFfix(translations):=20memoize=20array?= =?UTF-8?q?=20translation=20(#2358)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit addresses an issue where array translations were created as new objects within the core module on each render cycle, causing unnecessary rerenders. By memoizing the translation object in the material renderer set, this commit prevents redundant rerenders. This commit also adds memorization to the attributes of the material oneOfRenderer to further avoid unnecessary rerendering. Co-authored-by: Stefan Dirix --- .../library/layouts/array-layout.renderer.ts | 25 ++++-- .../src/library/other/master-detail/master.ts | 21 ++++- .../src/library/other/table.renderer.ts | 6 +- packages/angular/src/library/array-control.ts | 18 ++++- packages/core/src/mappers/renderer.ts | 33 +------- .../MaterialListWithDetailRenderer.tsx | 12 ++- .../complex/MaterialArrayControlRenderer.tsx | 31 ++++--- .../src/complex/MaterialOneOfRenderer.tsx | 20 +++-- .../src/complex/MaterialTableControl.tsx | 3 +- .../src/layouts/MaterialArrayLayout.tsx | 7 +- .../layouts/MaterialArrayLayoutRenderer.tsx | 22 +++-- packages/react/src/JsonFormsContext.tsx | 20 +++++ .../src/complex/TableArrayControl.tsx | 15 +++- .../complex/array/ArrayControlRenderer.tsx | 13 ++- .../src/array/ArrayListRenderer.vue | 17 +++- .../vue-vanilla/src/complex/OneOfRenderer.vue | 24 ++++-- .../src/additional/ListWithDetailRenderer.vue | 2 +- .../src/complex/ArrayControlRenderer.vue | 2 +- .../vue-vuetify/src/complex/OneOfRenderer.vue | 21 ++++- .../src/complex/OneOfTabRenderer.vue | 4 +- .../src/layouts/ArrayLayoutRenderer.vue | 2 +- packages/vue-vuetify/src/util/composition.ts | 49 +++++++++++ .../additional/ListWithDetailRenderer.spec.ts | 58 +++++++++++++ .../ListWithDetailRenderer.spec.ts.snap | 41 ++++++++++ .../unit/complex/ArrayControlRenderer.spec.ts | 57 +++++++++++++ .../tests/unit/complex/OneOfRenderer.spec.ts | 81 +++++++++++++++++++ .../ArrayControlRenderer.spec.ts.snap | 78 ++++++++++++++++++ .../__snapshots__/OneOfRenderer.spec.ts.snap | 66 +++++++++++++++ .../unit/layout/ArrayLayoutRenderer.spec.ts | 58 +++++++++++++ .../ArrayLayoutRenderer.spec.ts.snap | 66 +++++++++++++++ .../tests/unit/util/TestComponent.vue | 1 + packages/vue-vuetify/tests/unit/util/util.ts | 6 +- 32 files changed, 785 insertions(+), 94 deletions(-) create mode 100644 packages/vue-vuetify/tests/unit/additional/ListWithDetailRenderer.spec.ts create mode 100644 packages/vue-vuetify/tests/unit/additional/__snapshots__/ListWithDetailRenderer.spec.ts.snap create mode 100644 packages/vue-vuetify/tests/unit/complex/ArrayControlRenderer.spec.ts create mode 100644 packages/vue-vuetify/tests/unit/complex/OneOfRenderer.spec.ts create mode 100644 packages/vue-vuetify/tests/unit/complex/__snapshots__/ArrayControlRenderer.spec.ts.snap create mode 100644 packages/vue-vuetify/tests/unit/complex/__snapshots__/OneOfRenderer.spec.ts.snap create mode 100644 packages/vue-vuetify/tests/unit/layout/ArrayLayoutRenderer.spec.ts create mode 100644 packages/vue-vuetify/tests/unit/layout/__snapshots__/ArrayLayoutRenderer.spec.ts.snap diff --git a/packages/angular-material/src/library/layouts/array-layout.renderer.ts b/packages/angular-material/src/library/layouts/array-layout.renderer.ts index 9cf7b6c9af..9f8850600f 100644 --- a/packages/angular-material/src/library/layouts/array-layout.renderer.ts +++ b/packages/angular-material/src/library/layouts/array-layout.renderer.ts @@ -33,10 +33,13 @@ import { JsonFormsAbstractControl, } from '@jsonforms/angular'; import { + arrayDefaultTranslations, ArrayLayoutProps, ArrayTranslations, createDefaultValue, + defaultJsonFormsI18nState, findUISchema, + getArrayTranslations, isObjectArrayWithNesting, JsonFormsState, mapDispatchToArrayControlProps, @@ -169,7 +172,7 @@ export class ArrayLayoutRenderer implements OnInit, OnDestroy { noData: boolean; - translations: ArrayTranslations; + translations: ArrayTranslations = {}; addItem: (path: string, value: any) => () => void; moveItemUp: (path: string, index: number) => () => void; moveItemDown: (path: string, index: number) => () => void; @@ -181,9 +184,19 @@ export class ArrayLayoutRenderer constructor(jsonFormsService: JsonFormsAngularService) { super(jsonFormsService); } - mapToProps(state: JsonFormsState): StatePropsOfArrayLayout { + mapToProps( + state: JsonFormsState + ): StatePropsOfArrayLayout & { translations: ArrayTranslations } { const props = mapStateToArrayLayoutProps(state, this.getOwnProps()); - return { ...props }; + const t = + state.jsonforms.i18n?.translate ?? defaultJsonFormsI18nState.translate; + const translations = getArrayTranslations( + t, + arrayDefaultTranslations, + props.i18nKeyPrefix, + props.label + ); + return { ...props, translations }; } remove(index: number): void { this.removeItems(this.propsPath, [index])(); @@ -211,10 +224,12 @@ export class ArrayLayoutRenderer this.moveItemDown = moveDown; this.removeItems = removeItems; } - mapAdditionalProps(props: ArrayLayoutProps) { - this.translations = props.translations; + mapAdditionalProps( + props: ArrayLayoutProps & { translations: ArrayTranslations } + ) { this.noData = !props.data || props.data === 0; this.uischemas = props.uischemas; + this.translations = props.translations; } getProps(index: number): OwnPropsOfRenderer { const uischema = findUISchema( diff --git a/packages/angular-material/src/library/other/master-detail/master.ts b/packages/angular-material/src/library/other/master-detail/master.ts index 4669f9d3f9..d50d4f092b 100644 --- a/packages/angular-material/src/library/other/master-detail/master.ts +++ b/packages/angular-material/src/library/other/master-detail/master.ts @@ -36,11 +36,14 @@ import { } from '@jsonforms/angular'; import { ArrayControlProps, + arrayDefaultTranslations, ArrayTranslations, ControlElement, createDefaultValue, decode, + defaultJsonFormsI18nState, findUISchema, + getArrayTranslations, getFirstPrimitiveProp, JsonFormsState, mapDispatchToArrayControlProps, @@ -194,7 +197,9 @@ export class MasterListComponent this.removeItems = removeItems; } - mapAdditionalProps(props: ArrayControlProps) { + mapAdditionalProps( + props: ArrayControlProps & { translations: ArrayTranslations } + ) { const { data, path, schema, uischema } = props; const controlElement = uischema as ControlElement; this.propsPath = props.path; @@ -282,9 +287,19 @@ export class MasterListComponent this.removeItems(this.propsPath, [item])(); } - protected mapToProps(state: JsonFormsState): StatePropsOfArrayControl { + protected mapToProps( + state: JsonFormsState + ): StatePropsOfArrayControl & { translations: ArrayTranslations } { const props = mapStateToArrayControlProps(state, this.getOwnProps()); - return { ...props }; + const t = + state.jsonforms.i18n?.translate ?? defaultJsonFormsI18nState.translate; + const translations = getArrayTranslations( + t, + arrayDefaultTranslations, + props.i18nKeyPrefix, + props.label + ); + return { ...props, translations }; } } diff --git a/packages/angular-material/src/library/other/table.renderer.ts b/packages/angular-material/src/library/other/table.renderer.ts index 5f38a9f6a6..3be3d7aaa5 100644 --- a/packages/angular-material/src/library/other/table.renderer.ts +++ b/packages/angular-material/src/library/other/table.renderer.ts @@ -158,7 +158,7 @@ export class TableRenderer extends JsonFormsArrayControl implements OnInit { moveItemUp: (path: string, index: number) => () => void; moveItemDown: (path: string, index: number) => () => void; removeItems: (path: string, toDelete: number[]) => () => void; - translations: ArrayTranslations; + translations: ArrayTranslations = {}; constructor(jsonformsService: JsonFormsAngularService) { super(jsonformsService); @@ -166,7 +166,9 @@ export class TableRenderer extends JsonFormsArrayControl implements OnInit { trackElement(index: number, _element: any) { return index ? index : null; } - mapAdditionalProps(props: ArrayControlProps) { + mapAdditionalProps( + props: ArrayControlProps & { translations: ArrayTranslations } + ) { this.items = this.generateCells(props.schema, props.path); this.displayedColumns = this.items.map((item) => item.property); if (this.isEnabled()) { diff --git a/packages/angular/src/library/array-control.ts b/packages/angular/src/library/array-control.ts index 013f6cd613..5e0bfbc5e5 100644 --- a/packages/angular/src/library/array-control.ts +++ b/packages/angular/src/library/array-control.ts @@ -23,6 +23,10 @@ THE SOFTWARE. */ import { + arrayDefaultTranslations, + ArrayTranslations, + defaultJsonFormsI18nState, + getArrayTranslations, JsonFormsState, mapStateToArrayControlProps, StatePropsOfArrayControl, @@ -34,8 +38,18 @@ export class JsonFormsArrayControl extends JsonFormsAbstractControl implements OnInit, OnDestroy { - protected mapToProps(state: JsonFormsState): StatePropsOfArrayControl { + protected mapToProps( + state: JsonFormsState + ): StatePropsOfArrayControl & { translations: ArrayTranslations } { const props = mapStateToArrayControlProps(state, this.getOwnProps()); - return { ...props }; + const t = + state.jsonforms.i18n?.translate ?? defaultJsonFormsI18nState.translate; + const translations = getArrayTranslations( + t, + arrayDefaultTranslations, + props.i18nKeyPrefix, + props.label + ); + return { ...props, translations }; } } diff --git a/packages/core/src/mappers/renderer.ts b/packages/core/src/mappers/renderer.ts index 2a80de8e69..9883d50632 100644 --- a/packages/core/src/mappers/renderer.ts +++ b/packages/core/src/mappers/renderer.ts @@ -47,13 +47,8 @@ import { getI18nKey, getI18nKeyPrefix, getI18nKeyPrefixBySchema, - getArrayTranslations, - CombinatorTranslations, - getCombinatorTranslations, - combinatorDefaultTranslations, getTranslator, getErrorTranslator, - arrayDefaultTranslations, ArrayTranslations, } from '../i18n'; import cloneDeep from 'lodash/cloneDeep'; @@ -790,7 +785,6 @@ export interface ControlWithDetailProps */ export interface StatePropsOfArrayControl extends StatePropsOfControlWithDetail { - translations: ArrayTranslations; childErrors?: ErrorObject[]; } @@ -805,12 +799,11 @@ export const mapStateToArrayControlProps = ( state: JsonFormsState, ownProps: OwnPropsOfControl ): StatePropsOfArrayControl => { - const { path, schema, uischema, i18nKeyPrefix, label, ...props } = + const { path, schema, uischema, label, ...props } = mapStateToControlWithDetailProps(state, ownProps); const resolvedSchema = Resolve.schema(schema, 'items', props.rootSchema); const childErrors = getSubErrorsAt(path, resolvedSchema)(state); - const t = getTranslator()(state); return { ...props, @@ -821,12 +814,6 @@ export const mapStateToArrayControlProps = ( childErrors, renderers: ownProps.renderers || getRenderers(state), cells: ownProps.cells || getCells(state), - translations: getArrayTranslations( - t, - arrayDefaultTranslations, - i18nKeyPrefix, - label - ), }; }; @@ -1061,7 +1048,6 @@ export interface StatePropsOfCombinator extends StatePropsOfControl { indexOfFittingSchema: number; uischemas: JsonFormsUISchemaRegistryEntry[]; data: any; - translations: CombinatorTranslations; } export const mapStateToCombinatorRendererProps = ( @@ -1073,13 +1059,6 @@ export const mapStateToCombinatorRendererProps = ( mapStateToControlProps(state, ownProps); const ajv = state.jsonforms.core.ajv; - const t = getTranslator()(state); - const translations = getCombinatorTranslations( - t, - combinatorDefaultTranslations, - i18nKeyPrefix, - label - ); const structuralKeywords = [ 'required', 'additionalProperties', @@ -1126,7 +1105,6 @@ export const mapStateToCombinatorRendererProps = ( label, indexOfFittingSchema, uischemas: getUISchemas(state), - translations, }; }; @@ -1161,7 +1139,6 @@ export const mapStateToOneOfProps = ( export interface StatePropsOfArrayLayout extends StatePropsOfControlWithDetail { data: number; - translations: ArrayTranslations; minItems?: number; disableRemove?: boolean; disableAdd?: boolean; @@ -1177,7 +1154,7 @@ export const mapStateToArrayLayoutProps = ( state: JsonFormsState, ownProps: OwnPropsOfControl ): StatePropsOfArrayLayout => { - const { path, schema, uischema, errors, i18nKeyPrefix, label, ...props } = + const { path, schema, uischema, errors, label, ...props } = mapStateToControlWithDetailProps(state, ownProps); const resolvedSchema = Resolve.schema(schema, 'items', props.rootSchema); @@ -1205,12 +1182,6 @@ export const mapStateToArrayLayoutProps = ( data: props.data ? props.data.length : 0, errors: allErrors, minItems: schema.minItems, - translations: getArrayTranslations( - t, - arrayDefaultTranslations, - i18nKeyPrefix, - label - ), }; }; diff --git a/packages/material-renderers/src/additional/MaterialListWithDetailRenderer.tsx b/packages/material-renderers/src/additional/MaterialListWithDetailRenderer.tsx index ba943d3f79..22cbc22298 100644 --- a/packages/material-renderers/src/additional/MaterialListWithDetailRenderer.tsx +++ b/packages/material-renderers/src/additional/MaterialListWithDetailRenderer.tsx @@ -25,6 +25,7 @@ import { and, ArrayLayoutProps, + ArrayTranslations, composePaths, computeLabel, createDefaultValue, @@ -36,7 +37,9 @@ import { } from '@jsonforms/core'; import { JsonFormsDispatch, + withArrayTranslationProps, withJsonFormsArrayLayoutProps, + withTranslateProps, } from '@jsonforms/react'; import { Grid, List, Typography } from '@mui/material'; import map from 'lodash/map'; @@ -63,11 +66,11 @@ export const MaterialListWithDetailRenderer = ({ cells, config, rootSchema, - translations, description, disableAdd, disableRemove, -}: ArrayLayoutProps) => { + translations, +}: ArrayLayoutProps & { translations: ArrayTranslations }) => { const [selectedIndex, setSelectedIndex] = useState(undefined); const handleRemoveItem = useCallback( (p: string, value: any) => () => { @@ -101,6 +104,7 @@ export const MaterialListWithDetailRenderer = ({ ), [uischemas, schema, uischema.scope, path, uischema, rootSchema] ); + const appliedUiSchemaOptions = merge({}, config, uischema.options); const doDisableAdd = disableAdd || appliedUiSchemaOptions.disableAdd; const doDisableRemove = disableRemove || appliedUiSchemaOptions.disableRemove; @@ -179,4 +183,6 @@ export const materialListWithDetailTester: RankedTester = rankWith( and(uiTypeIs('ListWithDetail'), isObjectArray) ); -export default withJsonFormsArrayLayoutProps(MaterialListWithDetailRenderer); +export default withJsonFormsArrayLayoutProps( + withTranslateProps(withArrayTranslationProps(MaterialListWithDetailRenderer)) +); diff --git a/packages/material-renderers/src/complex/MaterialArrayControlRenderer.tsx b/packages/material-renderers/src/complex/MaterialArrayControlRenderer.tsx index 346312b71f..8906ccbbb1 100644 --- a/packages/material-renderers/src/complex/MaterialArrayControlRenderer.tsx +++ b/packages/material-renderers/src/complex/MaterialArrayControlRenderer.tsx @@ -25,21 +25,28 @@ import React, { useCallback, useState } from 'react'; import { ArrayLayoutProps, + ArrayTranslations, RankedTester, isObjectArrayControl, isPrimitiveArrayControl, or, rankWith, } from '@jsonforms/core'; -import { withJsonFormsArrayLayoutProps } from '@jsonforms/react'; +import { + withArrayTranslationProps, + withJsonFormsArrayLayoutProps, + withTranslateProps, +} from '@jsonforms/react'; import { MaterialTableControl } from './MaterialTableControl'; import { DeleteDialog } from './DeleteDialog'; -export const MaterialArrayControlRenderer = (props: ArrayLayoutProps) => { +export const MaterialArrayControlRenderer = ( + props: ArrayLayoutProps & { translations: ArrayTranslations } +) => { const [open, setOpen] = useState(false); const [path, setPath] = useState(undefined); const [rowData, setRowData] = useState(undefined); - const { removeItems, visible } = props; + const { removeItems, visible, translations } = props; const openDeleteDialog = useCallback( (p: string, rowIndex: number) => { @@ -63,16 +70,20 @@ export const MaterialArrayControlRenderer = (props: ArrayLayoutProps) => { return ( <> - + ); @@ -83,4 +94,6 @@ export const materialArrayControlTester: RankedTester = rankWith( or(isObjectArrayControl, isPrimitiveArrayControl) ); -export default withJsonFormsArrayLayoutProps(MaterialArrayControlRenderer); +export default withJsonFormsArrayLayoutProps( + withTranslateProps(withArrayTranslationProps(MaterialArrayControlRenderer)) +); diff --git a/packages/material-renderers/src/complex/MaterialOneOfRenderer.tsx b/packages/material-renderers/src/complex/MaterialOneOfRenderer.tsx index fceca27dfe..ac6aad5230 100644 --- a/packages/material-renderers/src/complex/MaterialOneOfRenderer.tsx +++ b/packages/material-renderers/src/complex/MaterialOneOfRenderer.tsx @@ -22,7 +22,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -import React, { useCallback, useState } from 'react'; +import React, { useCallback, useMemo, useState } from 'react'; import isEmpty from 'lodash/isEmpty'; import { TabSwitchConfirmDialog } from './TabSwitchConfirmDialog'; @@ -69,13 +69,17 @@ export const MaterialOneOfRenderer = ({ const cancel = useCallback(() => { setConfirmDialogOpen(false); }, [setConfirmDialogOpen]); - const oneOfRenderInfos = createCombinatorRenderInfos( - (schema as JsonSchema).oneOf, - rootSchema, - 'oneOf', - uischema, - path, - uischemas + const oneOfRenderInfos = useMemo( + () => + createCombinatorRenderInfos( + (schema as JsonSchema).oneOf, + rootSchema, + 'oneOf', + uischema, + path, + uischemas + ), + [schema, rootSchema, uischema, path, uischemas] ); const openNewTab = (newIndex: number) => { diff --git a/packages/material-renderers/src/complex/MaterialTableControl.tsx b/packages/material-renderers/src/complex/MaterialTableControl.tsx index e221894a88..00239fc6c0 100644 --- a/packages/material-renderers/src/complex/MaterialTableControl.tsx +++ b/packages/material-renderers/src/complex/MaterialTableControl.tsx @@ -451,7 +451,8 @@ const TableRows = ({ }; export class MaterialTableControl extends React.Component< - ArrayLayoutProps & WithDeleteDialogSupport, + ArrayLayoutProps & + WithDeleteDialogSupport & { translations: ArrayTranslations }, any > { addItem = (path: string, value: any) => this.props.addItem(path, value); diff --git a/packages/material-renderers/src/layouts/MaterialArrayLayout.tsx b/packages/material-renderers/src/layouts/MaterialArrayLayout.tsx index 6cec1d884d..6846fd421e 100644 --- a/packages/material-renderers/src/layouts/MaterialArrayLayout.tsx +++ b/packages/material-renderers/src/layouts/MaterialArrayLayout.tsx @@ -26,6 +26,7 @@ import range from 'lodash/range'; import React, { useState, useCallback } from 'react'; import { ArrayLayoutProps, + ArrayTranslations, composePaths, computeLabel, createDefaultValue, @@ -35,7 +36,9 @@ import { ArrayLayoutToolbar } from './ArrayToolbar'; import ExpandPanelRenderer from './ExpandPanelRenderer'; import merge from 'lodash/merge'; -const MaterialArrayLayoutComponent = (props: ArrayLayoutProps) => { +const MaterialArrayLayoutComponent = ( + props: ArrayLayoutProps & { translations: ArrayTranslations } +) => { const [expanded, setExpanded] = useState(false); const innerCreateDefaultValue = useCallback( () => createDefaultValue(props.schema, props.rootSchema), @@ -65,10 +68,10 @@ const MaterialArrayLayoutComponent = (props: ArrayLayoutProps) => { rootSchema, config, uischemas, - translations, description, disableAdd, disableRemove, + translations, } = props; const appliedUiSchemaOptions = merge({}, config, props.uischema.options); const doDisableAdd = disableAdd || appliedUiSchemaOptions.disableAdd; diff --git a/packages/material-renderers/src/layouts/MaterialArrayLayoutRenderer.tsx b/packages/material-renderers/src/layouts/MaterialArrayLayoutRenderer.tsx index d684301431..2fd1001e29 100644 --- a/packages/material-renderers/src/layouts/MaterialArrayLayoutRenderer.tsx +++ b/packages/material-renderers/src/layouts/MaterialArrayLayoutRenderer.tsx @@ -26,29 +26,39 @@ import React, { useCallback } from 'react'; import { ArrayLayoutProps, + ArrayTranslations, isObjectArrayWithNesting, RankedTester, rankWith, } from '@jsonforms/core'; import { MaterialArrayLayout } from './MaterialArrayLayout'; -import { withJsonFormsArrayLayoutProps } from '@jsonforms/react'; +import { + withArrayTranslationProps, + withJsonFormsArrayLayoutProps, + withTranslateProps, +} from '@jsonforms/react'; export const MaterialArrayLayoutRenderer = ({ visible, addItem, + translations, ...props -}: ArrayLayoutProps) => { +}: ArrayLayoutProps & { translations: ArrayTranslations }) => { const addItemCb = useCallback( (p: string, value: any) => addItem(p, value), [addItem] ); - if (!visible) { return null; } return ( - + ); }; @@ -56,4 +66,6 @@ export const materialArrayLayoutTester: RankedTester = rankWith( 4, isObjectArrayWithNesting ); -export default withJsonFormsArrayLayoutProps(MaterialArrayLayoutRenderer); +export default withJsonFormsArrayLayoutProps( + withTranslateProps(withArrayTranslationProps(MaterialArrayLayoutRenderer)) +); diff --git a/packages/react/src/JsonFormsContext.tsx b/packages/react/src/JsonFormsContext.tsx index 84752883a3..b10323b65f 100644 --- a/packages/react/src/JsonFormsContext.tsx +++ b/packages/react/src/JsonFormsContext.tsx @@ -78,6 +78,9 @@ import { CoreActions, Middleware, defaultMiddleware, + arrayDefaultTranslations, + getArrayTranslations, + ArrayTranslations, } from '@jsonforms/core'; import debounce from 'lodash/debounce'; import React, { @@ -889,3 +892,20 @@ export const withTranslateProps =

( return ; }; + +export const withArrayTranslationProps =

( + Component: ComponentType

+) => + function withArrayTranslatationProps(props: P & TranslateProps) { + const translations = useMemo( + () => + getArrayTranslations( + props.t, + arrayDefaultTranslations, + props.i18nKeyPrefix, + props.label + ), + [props.t, props.i18nKeyPrefix, props.label] + ); + return ; + }; diff --git a/packages/vanilla-renderers/src/complex/TableArrayControl.tsx b/packages/vanilla-renderers/src/complex/TableArrayControl.tsx index 609eb178bc..2319f80bf1 100644 --- a/packages/vanilla-renderers/src/complex/TableArrayControl.tsx +++ b/packages/vanilla-renderers/src/complex/TableArrayControl.tsx @@ -41,8 +41,14 @@ import { Test, getControlPath, encode, + ArrayTranslations, } from '@jsonforms/core'; -import { DispatchCell, withJsonFormsArrayControlProps } from '@jsonforms/react'; +import { + DispatchCell, + withArrayTranslationProps, + withJsonFormsArrayControlProps, + withTranslateProps, +} from '@jsonforms/react'; import { withVanillaControlProps } from '../util'; import type { VanillaRendererProps } from '../index'; @@ -61,7 +67,8 @@ export const tableArrayControlTester: RankedTester = rankWith( ); class TableArrayControl extends React.Component< - ArrayControlProps & VanillaRendererProps, + ArrayControlProps & + VanillaRendererProps & { translations: ArrayTranslations }, any > { confirmDelete = (path: string, index: number) => { @@ -243,5 +250,7 @@ class TableArrayControl extends React.Component< } export default withVanillaControlProps( - withJsonFormsArrayControlProps(TableArrayControl) + withJsonFormsArrayControlProps( + withTranslateProps(withArrayTranslationProps(TableArrayControl)) + ) ); diff --git a/packages/vanilla-renderers/src/complex/array/ArrayControlRenderer.tsx b/packages/vanilla-renderers/src/complex/array/ArrayControlRenderer.tsx index 5c194e29ea..b287d37d82 100644 --- a/packages/vanilla-renderers/src/complex/array/ArrayControlRenderer.tsx +++ b/packages/vanilla-renderers/src/complex/array/ArrayControlRenderer.tsx @@ -31,10 +31,13 @@ import { findUISchema, Helpers, ControlElement, + ArrayTranslations, } from '@jsonforms/core'; import { JsonFormsDispatch, + withArrayTranslationProps, withJsonFormsArrayControlProps, + withTranslateProps, } from '@jsonforms/react'; import type { VanillaRendererProps } from '../../index'; import { withVanillaControlProps } from '../../util'; @@ -59,7 +62,8 @@ export const ArrayControl = ({ rootSchema, translations, enabled, -}: ArrayControlProps & VanillaRendererProps) => { +}: ArrayControlProps & + VanillaRendererProps & { translations: ArrayTranslations }) => { const controlElement = uischema as ControlElement; const childUiSchema = useMemo( () => @@ -189,7 +193,8 @@ export const ArrayControlRenderer = ({ enabled, errors, translations, -}: ArrayControlProps & VanillaRendererProps) => { +}: ArrayControlProps & + VanillaRendererProps & { translations: ArrayTranslations }) => { const controlElement = uischema as ControlElement; const labelDescription = Helpers.createLabelDescriptionFrom( controlElement, @@ -235,5 +240,7 @@ export const ArrayControlRenderer = ({ }; export default withVanillaControlProps( - withJsonFormsArrayControlProps(ArrayControlRenderer) + withJsonFormsArrayControlProps( + withTranslateProps(withArrayTranslationProps(ArrayControlRenderer)) + ) ); diff --git a/packages/vue-vanilla/src/array/ArrayListRenderer.vue b/packages/vue-vanilla/src/array/ArrayListRenderer.vue index 5cc004e88d..b54376e682 100644 --- a/packages/vue-vanilla/src/array/ArrayListRenderer.vue +++ b/packages/vue-vanilla/src/array/ArrayListRenderer.vue @@ -41,7 +41,7 @@

- {{ control.translations.noDataMessage }} + {{ translations.noDataMessage }}
@@ -56,8 +56,12 @@ import { schemaTypeIs, Resolve, JsonSchema, + JsonFormsSubStates, + arrayDefaultTranslations, + getArrayTranslations, + defaultJsonFormsI18nState, } from '@jsonforms/core'; -import { defineComponent } from 'vue'; +import { defineComponent, inject } from 'vue'; import { DispatchRenderer, rendererProps, @@ -106,6 +110,15 @@ const controlRenderer = defineComponent({ this.control.data.length <= this.arraySchema.minItems ); }, + translations(): any { + const jsonforms = inject('jsonforms'); + return getArrayTranslations( + jsonforms?.i18n?.translate ?? defaultJsonFormsI18nState.translate, + arrayDefaultTranslations, + this.control.i18nKeyPrefix, + this.control.label + ); + }, }, methods: { composePaths, diff --git a/packages/vue-vanilla/src/complex/OneOfRenderer.vue b/packages/vue-vanilla/src/complex/OneOfRenderer.vue index 471d89dd7d..b676662bb9 100644 --- a/packages/vue-vanilla/src/complex/OneOfRenderer.vue +++ b/packages/vue-vanilla/src/complex/OneOfRenderer.vue @@ -45,23 +45,23 @@

- {{ control.translations.clearDialogTitle }} + {{ translations.clearDialogTitle }}

- {{ control.translations.clearDialogMessage }} + {{ translations.clearDialogMessage }}

@@ -70,12 +70,16 @@