Skip to content

Commit

Permalink
Use schema title attribute where appropriate
Browse files Browse the repository at this point in the history
The label utility will now return the schema title if no other label was
defined via the ui schema.

Within the ui schema a label can be optionally defined for each control.
Previously if there was none, we fell back to auto-generating a label
from the given control scope. Now we will check the schema title
beforehand and return that if no label was defined for the control.

This also affects the ui schema generation which will no longer
auto-generate labels based on each control's scope.

Includes testcases.
  • Loading branch information
sdirix committed Apr 18, 2019
1 parent 083594e commit 025ce39
Show file tree
Hide file tree
Showing 16 changed files with 416 additions and 128 deletions.
2 changes: 1 addition & 1 deletion packages/core/src/generators/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
16 changes: 3 additions & 13 deletions packages/core/src/generators/uischema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
});

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
6 changes: 5 additions & 1 deletion packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
70 changes: 32 additions & 38 deletions packages/core/src/util/label.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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
});
5 changes: 2 additions & 3 deletions packages/core/src/util/renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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,
Expand Down
33 changes: 0 additions & 33 deletions packages/core/test/generators/uischema.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down Expand Up @@ -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 = {
Expand All @@ -187,7 +179,6 @@ test('generate ui schema for schema without object root', t => {
type: 'string'
};
const control: ControlElement = {
label: '',
type: 'Control',
scope: '#'
};
Expand All @@ -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 = {
Expand Down Expand Up @@ -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 = {
Expand Down Expand Up @@ -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 = {
Expand Down Expand Up @@ -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[]
Expand All @@ -409,7 +384,6 @@ test('generate named array control', t => {
}
};
const control: ControlElement = {
label: 'Comments',
type: 'Control',
scope: '#/properties/comments'
};
Expand All @@ -430,7 +404,6 @@ test('generate unnamed array control', t => {
}
};
const control: ControlElement = {
label: '',
type: 'Control',
scope: '#'
};
Expand All @@ -450,7 +423,6 @@ test('generate unnamed array control w/o type', t => {
}
};
const control = {
label: '',
type: 'Control',
scope: '#'
};
Expand Down Expand Up @@ -495,7 +467,6 @@ test('generate control for oneOf', t => {
]
};
const control = {
label: '',
type: 'Control',
scope: '#'
};
Expand All @@ -522,7 +493,6 @@ test('generate control for anyOf', t => {
]
};
const control = {
label: '',
type: 'Control',
scope: '#'
};
Expand All @@ -549,7 +519,6 @@ test('generate control for allOf', t => {
]
};
const control = {
label: '',
type: 'Control',
scope: '#'
};
Expand Down Expand Up @@ -582,7 +551,6 @@ test('no separate control for oneOf in array', t => {
}
};
const control = {
label: 'Myarray',
type: 'Control',
scope: '#/properties/myarray'
};
Expand Down Expand Up @@ -617,7 +585,6 @@ test('generate control for nested oneOf', t => {
}
};
const control = {
label: 'Name Or Age',
type: 'Control',
scope: '#/properties/myarray/properties/nameOrAge'
};
Expand Down
Loading

0 comments on commit 025ce39

Please sign in to comment.