diff --git a/packages/core/src/generators/index.ts b/packages/core/src/generators/index.ts index d2a89e1b8..12a8c44db 100644 --- a/packages/core/src/generators/index.ts +++ b/packages/core/src/generators/index.ts @@ -34,7 +34,7 @@ export const Generate: { layoutType?: string, prefix?: string ): UISchemaElement; - controlElement(label: string, ref: string): ControlElement; + controlElement(ref: string): ControlElement; } = { jsonSchema: generateJsonSchema, uiSchema: generateDefaultUISchema, diff --git a/packages/core/src/generators/uischema.ts b/packages/core/src/generators/uischema.ts index 7e7bca207..3441236c8 100644 --- a/packages/core/src/generators/uischema.ts +++ b/packages/core/src/generators/uischema.ts @@ -49,12 +49,8 @@ const createLayout = (layoutType: string): Layout => ({ /** * Creates a IControlObject with the given label referencing the given ref */ -export const createControlElement = ( - label: string, - ref: string -): ControlElement => ({ +export const createControlElement = (ref: string): ControlElement => ({ type: 'Control', - label: label === undefined ? false : label, scope: ref }); @@ -138,10 +134,7 @@ const generateUISchema = ( } if (isCombinator(jsonSchema)) { - const controlObject: ControlElement = createControlElement( - startCase(schemaName), - currentRef - ); + const controlObject: ControlElement = createControlElement(currentRef); schemaElements.push(controlObject); return controlObject; @@ -189,10 +182,7 @@ const generateUISchema = ( case 'integer': /* falls through */ case 'boolean': - const controlObject: ControlElement = createControlElement( - startCase(schemaName), - currentRef - ); + const controlObject: ControlElement = createControlElement(currentRef); schemaElements.push(controlObject); return controlObject; diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index dd3c2e7c7..5d2d9ee23 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -42,9 +42,13 @@ export { Test }; import { convertToValidClassName, createLabelDescriptionFrom } from './util'; import { ControlElement, LabelDescription } from './models/uischema'; +import { JsonSchema } from './models/jsonSchema'; const Helpers: { - createLabelDescriptionFrom(withLabel: ControlElement): LabelDescription; + createLabelDescriptionFrom( + withLabel: ControlElement, + schema: JsonSchema + ): LabelDescription; convertToValidClassName(s: string): string; } = { createLabelDescriptionFrom, diff --git a/packages/core/src/util/label.ts b/packages/core/src/util/label.ts index d3f233769..267d439c6 100644 --- a/packages/core/src/util/label.ts +++ b/packages/core/src/util/label.ts @@ -25,9 +25,16 @@ import startCase from 'lodash/startCase'; import { ControlElement, LabelDescription } from '../models/uischema'; +import { JsonSchema } from '../models/jsonSchema'; -const deriveLabel = (controlElement: ControlElement): string => { - if (controlElement.scope !== undefined) { +const deriveLabel = ( + controlElement: ControlElement, + schemaElement?: JsonSchema +): string => { + if (schemaElement && typeof schemaElement.title === 'string') { + return schemaElement.title; + } + if (typeof controlElement.scope === 'string') { const ref = controlElement.scope; const label = ref.substr(ref.lastIndexOf('/') + 1); @@ -42,48 +49,35 @@ export const createCleanLabel = (label: string): string => { }; /** - * Return a label object based on the given control element. + * Return a label object based on the given control and schema element. * @param {ControlElement} withLabel the UI schema to obtain a label object for + * @param {JsonSchema} schema optional: the corresponding schema element * @returns {LabelDescription} */ export const createLabelDescriptionFrom = ( - withLabel: ControlElement + withLabel: ControlElement, + schema?: JsonSchema ): LabelDescription => { const labelProperty = withLabel.label; - const derivedLabel = deriveLabel(withLabel); if (typeof labelProperty === 'boolean') { - if (labelProperty) { - return { - text: derivedLabel, - show: labelProperty - }; - } else { - return { - text: derivedLabel, - show: labelProperty as boolean - }; - } - } else if (typeof labelProperty === 'string') { - return { - text: labelProperty as string, - show: true - }; - } else if (typeof labelProperty === 'object') { - const show = labelProperty.hasOwnProperty('show') - ? labelProperty.show - : true; - const label = labelProperty.hasOwnProperty('text') - ? labelProperty.text - : derivedLabel; - - return { - text: label, - show - }; - } else { - return { - text: derivedLabel, - show: true - }; + return labelDescription(deriveLabel(withLabel, schema), labelProperty); + } + if (typeof labelProperty === 'string') { + return labelDescription(labelProperty, true); } + if (typeof labelProperty === 'object') { + const label = + typeof labelProperty.text === 'string' + ? labelProperty.text + : deriveLabel(withLabel, schema); + const show = + typeof labelProperty.show === 'boolean' ? labelProperty.show : true; + return labelDescription(label, show); + } + return labelDescription(deriveLabel(withLabel, schema), true); }; + +const labelDescription = (text: string, show: boolean): LabelDescription => ({ + text: text, + show: show +}); diff --git a/packages/core/src/util/renderer.ts b/packages/core/src/util/renderer.ts index 203ec69bc..78c918e23 100644 --- a/packages/core/src/util/renderer.ts +++ b/packages/core/src/util/renderer.ts @@ -349,8 +349,6 @@ export const mapStateToControlProps = ( const enabled = has(ownProps, 'enabled') ? ownProps.enabled : isEnabled(uischema, rootData, ownProps.path); - const labelDesc = createLabelDescriptionFrom(uischema); - const label = labelDesc.show ? labelDesc.text : ''; const controlElement = uischema as ControlElement; const id = ownProps.id; const rootSchema = getSchema(state); @@ -368,7 +366,8 @@ export const mapStateToControlProps = ( const description = resolvedSchema !== undefined ? resolvedSchema.description : ''; const data = Resolve.data(rootData, path); - + const labelDesc = createLabelDescriptionFrom(uischema, resolvedSchema); + const label = labelDesc.show ? labelDesc.text : ''; return { data, description, diff --git a/packages/core/test/generators/uischema.test.ts b/packages/core/test/generators/uischema.test.ts index 9547b10b0..54e6d6277 100644 --- a/packages/core/test/generators/uischema.test.ts +++ b/packages/core/test/generators/uischema.test.ts @@ -95,38 +95,31 @@ test('generate ui schema for Control element by resolving refs', t => { }; const typeControl: ControlElement = { type: 'Control', - label: 'Type', scope: '#/properties/type' }; const labelControl: ControlElement = { type: 'Control', - label: 'Label', scope: '#/properties/label' }; const scopeControl: ControlElement = { type: 'Control', - label: 'Scope', scope: '#/properties/scope' }; const effectControl: ControlElement = { type: 'Control', - label: 'Effect', scope: '#/properties/rule/properties/effect' }; const conditionTypeControl: ControlElement = { type: 'Control', - label: 'Type', scope: '#/properties/rule/properties/condition/properties/type' }; const conditionScopeControl: ControlElement = { type: 'Control', - label: 'Scope', scope: '#/properties/rule/properties/condition/properties/scope' }; const conditionExpectedValueControl: ControlElement = { type: 'Control', - label: 'Expected Value', scope: '#/properties/rule/properties/condition/properties/expectedValue' }; const conditionLayout: VerticalLayout = { @@ -172,7 +165,6 @@ test('generate ui schema for schema with one property', t => { }; const control = { type: 'Control', - label: 'Name', scope: '#/properties/name' }; const uischema: Layout = { @@ -187,7 +179,6 @@ test('generate ui schema for schema without object root', t => { type: 'string' }; const control: ControlElement = { - label: '', type: 'Control', scope: '#' }; @@ -208,7 +199,6 @@ test('generate ui schema for schema with unspecified object root', t => { }; const controlElement = { type: 'Control', - label: 'Age', scope: '#/properties/age' }; const uischema: Layout = { @@ -237,12 +227,10 @@ test(`nested object attributes`, t => { }; const idControl: ControlElement = { type: 'Control', - label: 'Id', scope: '#/properties/id' }; const nameControl: ControlElement = { type: 'Control', - label: 'Name', scope: '#/properties/private/properties/name' }; const nestedLayout: VerticalLayout = { @@ -270,12 +258,10 @@ test(`don't ignore non-json-schema id attributes`, t => { }; const idControl: ControlElement = { type: 'Control', - label: 'Id', scope: '#/properties/id' }; const nameControl: ControlElement = { type: 'Control', - label: 'Name', scope: '#/properties/name' }; const uischema: Layout = { @@ -336,57 +322,46 @@ test('generate ui schema for schema with multiple properties', t => { elements: [ { type: 'Control', - label: 'Id', scope: '#/properties/id' }, { type: 'Control', - label: 'Last Name', scope: '#/properties/lastName' }, { type: 'Control', - label: 'Email', scope: '#/properties/email' }, { type: 'Control', - label: 'First Name', scope: '#/properties/firstName' }, { type: 'Control', - label: 'Gender', scope: '#/properties/gender' }, { type: 'Control', - label: 'Active', scope: '#/properties/active' }, { type: 'Control', - label: 'Registration Time', scope: '#/properties/registrationTime' }, { type: 'Control', - label: 'Weight', scope: '#/properties/weight' }, { type: 'Control', - label: 'Height', scope: '#/properties/height' }, { type: 'Control', - label: 'Nationality', scope: '#/properties/nationality' }, { type: 'Control', - label: 'Birth Date', scope: '#/properties/birthDate' } ] as ControlElement[] @@ -409,7 +384,6 @@ test('generate named array control', t => { } }; const control: ControlElement = { - label: 'Comments', type: 'Control', scope: '#/properties/comments' }; @@ -430,7 +404,6 @@ test('generate unnamed array control', t => { } }; const control: ControlElement = { - label: '', type: 'Control', scope: '#' }; @@ -450,7 +423,6 @@ test('generate unnamed array control w/o type', t => { } }; const control = { - label: '', type: 'Control', scope: '#' }; @@ -495,7 +467,6 @@ test('generate control for oneOf', t => { ] }; const control = { - label: '', type: 'Control', scope: '#' }; @@ -522,7 +493,6 @@ test('generate control for anyOf', t => { ] }; const control = { - label: '', type: 'Control', scope: '#' }; @@ -549,7 +519,6 @@ test('generate control for allOf', t => { ] }; const control = { - label: '', type: 'Control', scope: '#' }; @@ -582,7 +551,6 @@ test('no separate control for oneOf in array', t => { } }; const control = { - label: 'Myarray', type: 'Control', scope: '#/properties/myarray' }; @@ -617,7 +585,6 @@ test('generate control for nested oneOf', t => { } }; const control = { - label: 'Name Or Age', type: 'Control', scope: '#/properties/myarray/properties/nameOrAge' }; diff --git a/packages/core/test/util/label.test.ts b/packages/core/test/util/label.test.ts index 82d642300..3cc7f23e7 100644 --- a/packages/core/test/util/label.test.ts +++ b/packages/core/test/util/label.test.ts @@ -26,61 +26,62 @@ import test from 'ava'; import { ControlElement } from '../../src'; import { createLabelDescriptionFrom } from '../../src/util'; +import { JsonSchema } from '../../src/models/jsonSchema'; -test('control relative', t => { +test('control relative - no schema', t => { const controlElement: ControlElement = { type: 'Control', scope: '/properties/foo' }; - const labelObject = createLabelDescriptionFrom(controlElement); + const labelObject = createLabelDescriptionFrom(controlElement, undefined); t.is(labelObject.show, true); t.is(labelObject.text, 'Foo'); }); -test('control without label string, camel split', t => { +test('control without label string, camel split - no schema', t => { const controlElement: ControlElement = { type: 'Control', scope: '#/properties/fooBarBaz' }; - const labelObject = createLabelDescriptionFrom(controlElement); + const labelObject = createLabelDescriptionFrom(controlElement, undefined); t.is(labelObject.show, true); t.is(labelObject.text, 'Foo Bar Baz'); }); -test('control with label string', t => { +test('control with label string - no schema', t => { const controlElement: ControlElement = { type: 'Control', scope: '#/properties/foo', label: 'bar' }; - const labelObject = createLabelDescriptionFrom(controlElement); + const labelObject = createLabelDescriptionFrom(controlElement, undefined); t.is(labelObject.show, true); t.is(labelObject.text, 'bar'); }); -test('control with label boolean', t => { +test('control with label boolean - no schema', t => { const controlElement: ControlElement = { type: 'Control', scope: '#/properties/foo', label: true }; - const labelObject = createLabelDescriptionFrom(controlElement); + const labelObject = createLabelDescriptionFrom(controlElement, undefined); t.is(labelObject.show, true); t.is(labelObject.text, 'Foo'); }); -test('control with label object, empty', t => { +test('control with label object, empty - no schema', t => { const controlElement: ControlElement = { type: 'Control', scope: '#/properties/foo', label: {} }; - const labelObject = createLabelDescriptionFrom(controlElement); + const labelObject = createLabelDescriptionFrom(controlElement, undefined); t.is(labelObject.show, true); t.is(labelObject.text, 'Foo'); }); -test('control with label object, text-only', t => { +test('control with label object, text-only - no schema', t => { const controlElement: ControlElement = { type: 'Control', scope: '#/properties/foo', @@ -88,12 +89,12 @@ test('control with label object, text-only', t => { text: 'mega bar' } }; - const labelObject = createLabelDescriptionFrom(controlElement); + const labelObject = createLabelDescriptionFrom(controlElement, undefined); t.is(labelObject.show, true); t.is(labelObject.text, 'mega bar'); }); -test('control with label object, visible-only', t => { +test('control with label object, visible-only - no schema', t => { const controlElement: ControlElement = { type: 'Control', scope: '#/properties/foo', @@ -101,12 +102,12 @@ test('control with label object, visible-only', t => { show: true } }; - const labelObject = createLabelDescriptionFrom(controlElement); + const labelObject = createLabelDescriptionFrom(controlElement, undefined); t.is(labelObject.show, true); t.is(labelObject.text, 'Foo'); }); -test('control with label object, full', t => { +test('control with label object, full - no schema', t => { const controlElement: ControlElement = { type: 'Control', scope: '#/properties/foo', @@ -115,7 +116,249 @@ test('control with label object, full', t => { text: 'mega bar' } }; - const labelObject = createLabelDescriptionFrom(controlElement); + const labelObject = createLabelDescriptionFrom(controlElement, undefined); + t.is(labelObject.show, false); + t.is(labelObject.text, 'mega bar'); +}); + +test('control relative - schema without title', t => { + const controlElement: ControlElement = { + type: 'Control', + scope: '/properties/foo' + }; + const schema: JsonSchema = { + type: 'string' + }; + const labelObject = createLabelDescriptionFrom(controlElement, schema); + t.is(labelObject.show, true); + t.is(labelObject.text, 'Foo'); +}); + +test('control without label string, camel split - schema without title', t => { + const controlElement: ControlElement = { + type: 'Control', + scope: '#/properties/fooBarBaz' + }; + const schema: JsonSchema = { + type: 'string' + }; + const labelObject = createLabelDescriptionFrom(controlElement, schema); + t.is(labelObject.show, true); + t.is(labelObject.text, 'Foo Bar Baz'); +}); + +test('control with label string - schema without title', t => { + const controlElement: ControlElement = { + type: 'Control', + scope: '#/properties/foo', + label: 'bar' + }; + const schema: JsonSchema = { + type: 'string' + }; + const labelObject = createLabelDescriptionFrom(controlElement, schema); + t.is(labelObject.show, true); + t.is(labelObject.text, 'bar'); +}); + +test('control with label boolean - schema without title', t => { + const controlElement: ControlElement = { + type: 'Control', + scope: '#/properties/foo', + label: true + }; + const schema: JsonSchema = { + type: 'string' + }; + const labelObject = createLabelDescriptionFrom(controlElement, schema); + t.is(labelObject.show, true); + t.is(labelObject.text, 'Foo'); +}); + +test('control with label object, empty - schema without title', t => { + const controlElement: ControlElement = { + type: 'Control', + scope: '#/properties/foo', + label: {} + }; + const schema: JsonSchema = { + type: 'string' + }; + const labelObject = createLabelDescriptionFrom(controlElement, schema); + t.is(labelObject.show, true); + t.is(labelObject.text, 'Foo'); +}); + +test('control with label object, text-only - schema without title', t => { + const controlElement: ControlElement = { + type: 'Control', + scope: '#/properties/foo', + label: { + text: 'mega bar' + } + }; + const schema: JsonSchema = { + type: 'string' + }; + const labelObject = createLabelDescriptionFrom(controlElement, schema); + t.is(labelObject.show, true); + t.is(labelObject.text, 'mega bar'); +}); + +test('control with label object, visible-only - schema without title', t => { + const controlElement: ControlElement = { + type: 'Control', + scope: '#/properties/foo', + label: { + show: true + } + }; + const schema: JsonSchema = { + type: 'string' + }; + const labelObject = createLabelDescriptionFrom(controlElement, schema); + t.is(labelObject.show, true); + t.is(labelObject.text, 'Foo'); +}); + +test('control with label object, full - schema without title', t => { + const controlElement: ControlElement = { + type: 'Control', + scope: '#/properties/foo', + label: { + show: false, + text: 'mega bar' + } + }; + const schema: JsonSchema = { + type: 'string' + }; + const labelObject = createLabelDescriptionFrom(controlElement, schema); + t.is(labelObject.show, false); + t.is(labelObject.text, 'mega bar'); +}); + +test('control relative - schema with title', t => { + const controlElement: ControlElement = { + type: 'Control', + scope: '/properties/foo' + }; + const schema: JsonSchema = { + type: 'string', + title: 'Schema Title' + }; + const labelObject = createLabelDescriptionFrom(controlElement, schema); + t.is(labelObject.show, true); + t.is(labelObject.text, 'Schema Title'); +}); + +test('control without label string, camel split - schema with title', t => { + const controlElement: ControlElement = { + type: 'Control', + scope: '#/properties/fooBarBaz' + }; + const schema: JsonSchema = { + type: 'string', + title: 'Schema Title' + }; + const labelObject = createLabelDescriptionFrom(controlElement, schema); + t.is(labelObject.show, true); + t.is(labelObject.text, 'Schema Title'); +}); + +test('control with label string - schema with title', t => { + const controlElement: ControlElement = { + type: 'Control', + scope: '#/properties/foo', + label: 'bar' + }; + const schema: JsonSchema = { + type: 'string', + title: 'Schema Title' + }; + const labelObject = createLabelDescriptionFrom(controlElement, schema); + t.is(labelObject.show, true); + t.is(labelObject.text, 'bar'); +}); + +test('control with label boolean - schema with title', t => { + const controlElement: ControlElement = { + type: 'Control', + scope: '#/properties/foo', + label: true + }; + const schema: JsonSchema = { + type: 'string', + title: 'Schema Title' + }; + const labelObject = createLabelDescriptionFrom(controlElement, schema); + t.is(labelObject.show, true); + t.is(labelObject.text, 'Schema Title'); +}); + +test('control with label object, empty - schema with title', t => { + const controlElement: ControlElement = { + type: 'Control', + scope: '#/properties/foo', + label: {} + }; + const schema: JsonSchema = { + type: 'string', + title: 'Schema Title' + }; + const labelObject = createLabelDescriptionFrom(controlElement, schema); + t.is(labelObject.show, true); + t.is(labelObject.text, 'Schema Title'); +}); + +test('control with label object, text-only - schema with title', t => { + const controlElement: ControlElement = { + type: 'Control', + scope: '#/properties/foo', + label: { + text: 'mega bar' + } + }; + const schema: JsonSchema = { + type: 'string', + title: 'Schema Title' + }; + const labelObject = createLabelDescriptionFrom(controlElement, schema); + t.is(labelObject.show, true); + t.is(labelObject.text, 'mega bar'); +}); + +test('control with label object, visible-only - schema with title', t => { + const controlElement: ControlElement = { + type: 'Control', + scope: '#/properties/foo', + label: { + show: true + } + }; + const schema: JsonSchema = { + type: 'string', + title: 'Schema Title' + }; + const labelObject = createLabelDescriptionFrom(controlElement, schema); + t.is(labelObject.show, true); + t.is(labelObject.text, 'Schema Title'); +}); + +test('control with label object, full - schema with title', t => { + const controlElement: ControlElement = { + type: 'Control', + scope: '#/properties/foo', + label: { + show: false, + text: 'mega bar' + } + }; + const schema: JsonSchema = { + type: 'string', + title: 'Schema Title' + }; + const labelObject = createLabelDescriptionFrom(controlElement, schema); t.is(labelObject.show, false); t.is(labelObject.text, 'mega bar'); }); diff --git a/packages/examples/src/arrays-with-detail-and-rule.ts b/packages/examples/src/arrays-with-detail-and-rule.ts index 438100a16..98177b2c7 100644 --- a/packages/examples/src/arrays-with-detail-and-rule.ts +++ b/packages/examples/src/arrays-with-detail-and-rule.ts @@ -33,6 +33,7 @@ export const schema = { enableArray: { type: 'boolean' }, comments: { type: 'array', + title: 'Messages', items: { type: 'object', properties: { diff --git a/packages/examples/src/list-with-detail.ts b/packages/examples/src/list-with-detail.ts index 385f8edca..444121cd0 100644 --- a/packages/examples/src/list-with-detail.ts +++ b/packages/examples/src/list-with-detail.ts @@ -69,7 +69,8 @@ const schema = { }, title: { type: 'string', - minLength: 5 + minLength: 5, + title: 'Official Title' }, ordered: { type: 'boolean' }, processId: { diff --git a/packages/material/src/additional/MaterialListWithDetailRenderer.tsx b/packages/material/src/additional/MaterialListWithDetailRenderer.tsx index 0ef2f381a..0bbb2d17e 100644 --- a/packages/material/src/additional/MaterialListWithDetailRenderer.tsx +++ b/packages/material/src/additional/MaterialListWithDetailRenderer.tsx @@ -26,10 +26,11 @@ import { and, ArrayLayoutProps, composePaths, + computeLabel, createDefaultValue, findUISchema, getData, - Helpers, + isPlainLabel, isObjectArray, JsonFormsState, JsonSchema, @@ -85,15 +86,11 @@ export class MaterialListWithDetailRenderer extends React.Component< }; createDefaultValue = () => createDefaultValue(this.props.schema); render() { - const {uischema, visible, errors, path, data, schema} = this.props; - const labelDescription = Helpers.createLabelDescriptionFrom( - uischema - ); - const label = labelDescription.show ? labelDescription.text : ''; + const {required, visible, errors, path, data, schema, label} = this.props; return ( ({ + type: 'Control', + scope: scope, + label: false +}); + class NonEmptyCellInner extends React.Component { render() { const { path, propName, schema, rootSchema, errors } = this.props; @@ -176,16 +181,13 @@ class NonEmptyCellInner extends React.Component { `#/properties/${propName}`, rootSchema )} - uischema={Generate.controlElement( - undefined, - `#/properties/${propName}` - )} + uischema={controlWithoutLabel(`#/properties/${propName}`)} path={path} /> ) : ( )} diff --git a/packages/material/src/layouts/MaterialArrayLayout.tsx b/packages/material/src/layouts/MaterialArrayLayout.tsx index 7ce66ebed..86447650a 100644 --- a/packages/material/src/layouts/MaterialArrayLayout.tsx +++ b/packages/material/src/layouts/MaterialArrayLayout.tsx @@ -29,11 +29,12 @@ import React from 'react'; import { ArrayLayoutProps, composePaths, + computeLabel, ControlElement, createDefaultValue, findUISchema, getData, - Helpers, + isPlainLabel, JsonFormsRendererRegistryEntry, JsonFormsState, JsonSchema, @@ -81,15 +82,15 @@ export class MaterialArrayLayout extends React.Component { const materialArrayLayout = wrapper.find(MaterialArrayLayout); expect(materialArrayLayout.props().renderers).toHaveLength(0); - }) + }); + + it('ui schema label for array', () => { + const uischemaWithLabel = { + ...uischema, + label: "My awesome label" + } + const store = initJsonFormsStore(); + wrapper = mount( + + + + ); + + const listLabel = wrapper.find('h6').at(0); + expect(listLabel.text()).toBe('My awesome label'); + }); + + it('schema title for array', () => { + const titleSchema = { + ...schema, + title: "My awesome title" + }; + const store = initJsonFormsStore(); + wrapper = mount( + + + + ); + + const listTitle = wrapper.find('h6').at(0); + expect(listTitle.text()).toBe('My awesome title'); + }); }); diff --git a/packages/material/test/renderers/MaterialListWithDetailRenderer.test.tsx b/packages/material/test/renderers/MaterialListWithDetailRenderer.test.tsx index 3fe2ed2ff..a6af36130 100644 --- a/packages/material/test/renderers/MaterialListWithDetailRenderer.test.tsx +++ b/packages/material/test/renderers/MaterialListWithDetailRenderer.test.tsx @@ -57,7 +57,8 @@ const schema = { properties: { message: { type: 'string', - maxLength: 3 + maxLength: 3, + title: 'Schema Title' }, done: { type: 'boolean' @@ -197,6 +198,56 @@ describe('Material list with detail renderer', () => { expect(controlFirst.props().value).toBe('Yolo'); }); + it('ui schema label for list', () => { + const uischemaWithLabel = { + ...uischema, + label: "My awesome label" + } + const store = initJsonFormsStore(); + wrapper = mount( + + + + ); + + const listLabel = wrapper.find('h6').at(0); + expect(listLabel.text()).toBe('My awesome label'); + }); + + it('schema title for list', () => { + const titleSchema = { + ...schema, + title: "My awesome title" + }; + const store = initJsonFormsStore(); + wrapper = mount( + + + + ); + + const listTitle = wrapper.find('h6').at(0); + expect(listTitle.text()).toBe('My awesome title'); + }); + + it('choose appropriate labels in nested schema', () => { + const store = initJsonFormsStore(); + wrapper = mount( + + + + ); + + const liSecond = wrapper.find('div[role="button"]').at(1); + liSecond.simulate('click'); + + const labels = wrapper.find('label'); + expect(labels).toHaveLength(2); + + const label = labels.at(0); + expect(label.text()).toBe('Schema Title'); + }); + it('add data to the array', () => { const store = initJsonFormsStore(); wrapper = mount( diff --git a/packages/vanilla/src/complex/TableArrayControl.tsx b/packages/vanilla/src/complex/TableArrayControl.tsx index d486be218..c4271de6e 100644 --- a/packages/vanilla/src/complex/TableArrayControl.tsx +++ b/packages/vanilla/src/complex/TableArrayControl.tsx @@ -95,7 +95,7 @@ class TableArrayControl extends React.Component< label: false, scope: schema.type === 'object' ? `#/properties/${key}` : '#' }); - const labelObject = createLabelDescriptionFrom(controlElement); + const labelObject = createLabelDescriptionFrom(controlElement, schema); const isValid = errors.length === 0; const divClassNames = 'validation' + (isValid ? '' : ' validation_error'); const labelText = isPlainLabel(label) ? label : label.default; diff --git a/packages/vanilla/src/complex/array/ArrayControlRenderer.tsx b/packages/vanilla/src/complex/array/ArrayControlRenderer.tsx index e34b560fa..ca501ca1c 100644 --- a/packages/vanilla/src/complex/array/ArrayControlRenderer.tsx +++ b/packages/vanilla/src/complex/array/ArrayControlRenderer.tsx @@ -55,7 +55,7 @@ const ArrayControlRenderer = }: ArrayControlProps & VanillaRendererProps) => { const controlElement = uischema as ControlElement; - const labelDescription = Helpers.createLabelDescriptionFrom(controlElement); + const labelDescription = Helpers.createLabelDescriptionFrom(controlElement, schema); const label = labelDescription.show ? labelDescription.text : ''; const controlClassName = `control ${(Helpers.convertToValidClassName(controlElement.scope))}`;