diff --git a/packages/core/src/util/combinators.ts b/packages/core/src/util/combinators.ts index e502d229f..9ebb3b6cc 100644 --- a/packages/core/src/util/combinators.ts +++ b/packages/core/src/util/combinators.ts @@ -35,18 +35,6 @@ export interface CombinatorSubSchemaRenderInfo { export type CombinatorKeyword = 'anyOf' | 'oneOf' | 'allOf'; -const createLabel = ( - subSchema: JsonSchema, - subSchemaIndex: number, - keyword: CombinatorKeyword -): string => { - if (subSchema.title) { - return subSchema.title; - } else { - return keyword + '-' + subSchemaIndex; - } -}; - export const createCombinatorRenderInfos = ( combinatorSubSchemas: JsonSchema[], rootSchema: JsonSchema, @@ -56,9 +44,11 @@ export const createCombinatorRenderInfos = ( uischemas: JsonFormsUISchemaRegistryEntry[] ): CombinatorSubSchemaRenderInfo[] => combinatorSubSchemas.map((subSchema, subSchemaIndex) => { - const schema = subSchema.$ref - ? Resolve.schema(rootSchema, subSchema.$ref, rootSchema) - : subSchema; + const resolvedSubSchema = + subSchema.$ref && Resolve.schema(rootSchema, subSchema.$ref, rootSchema); + + const schema = resolvedSubSchema ?? subSchema; + return { schema, uischema: findUISchema( @@ -70,6 +60,9 @@ export const createCombinatorRenderInfos = ( control, rootSchema ), - label: createLabel(subSchema, subSchemaIndex, keyword), + label: + subSchema.title ?? + resolvedSubSchema.title ?? + `${keyword}-${subSchemaIndex}`, }; }); diff --git a/packages/core/test/util/combinators.test.ts b/packages/core/test/util/combinators.test.ts new file mode 100644 index 000000000..548760967 --- /dev/null +++ b/packages/core/test/util/combinators.test.ts @@ -0,0 +1,82 @@ +import test from 'ava'; +import { createCombinatorRenderInfos } from '../../src/util/combinators'; +import { ControlElement } from '../../src'; + +const rootSchema = { + type: 'object', + properties: { + widget: { + anyOf: [ + { + $ref: '#/definitions/Dua', + }, + { + $ref: '#/definitions/Lipa', + }, + ], + }, + }, + definitions: { + Dua: { + title: 'Dua', + type: 'object', + properties: { name: { type: 'string' } }, + }, + Lipa: { + title: 'Lipa', + type: 'object', + properties: { name: { type: 'string' } }, + }, + }, +}; + +const rootSchemaWithOverrides = { + ...rootSchema, + properties: { + ...rootSchema.properties, + widget: { + ...rootSchema.properties.widget, + anyOf: [ + { + ...rootSchema.properties.widget.anyOf[0], + title: 'DuaOverride', + }, + { + ...rootSchema.properties.widget.anyOf[1], + title: 'LipaOverride', + }, + ], + }, + }, +}; + +const control: ControlElement = { + type: 'Control', + scope: '#', +}; + +test('createCombinatorRenderInfos - uses titles for labels when subschemas are refs', (t) => { + const [duaRenderInfo, lipaRenderInfo] = createCombinatorRenderInfos( + rootSchema.properties.widget.anyOf, + rootSchema, + 'anyOf', + control, + 'widget', + [] + ); + t.deepEqual(duaRenderInfo.label, 'Dua'); + t.deepEqual(lipaRenderInfo.label, 'Lipa'); +}); + +test('createCombinatorRenderInfos - uses overrides for labels when subschemas are refs', (t) => { + const [duaRenderInfo, lipaRenderInfo] = createCombinatorRenderInfos( + rootSchemaWithOverrides.properties.widget.anyOf, + rootSchemaWithOverrides, + 'anyOf', + control, + 'widget', + [] + ); + t.deepEqual(duaRenderInfo.label, 'DuaOverride'); + t.deepEqual(lipaRenderInfo.label, 'LipaOverride'); +});