Skip to content

Commit 15aa6d1

Browse files
SabantuMonwabisi Sifumbamonwabisi-gaga
authored
Bug Fix: Allow a user to edit 'Section Display Name' and 'Section Description' of a pre-configured section component on the form builder. (#185)
bug: Add additionalProperties to supportedPropertyParameters Co-authored-by: Monwabisi Sifumba <[email protected]> Co-authored-by: Monwabisi Sifumba <[email protected]>
1 parent 5e1e71f commit 15aa6d1

File tree

4 files changed

+250
-21
lines changed

4 files changed

+250
-21
lines changed

src/formBuilder/FormBuilder.test.js

Lines changed: 157 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import React from 'react';
21
import { mount } from 'enzyme';
3-
2+
import React from 'react';
43
import FormBuilder from './FormBuilder';
54

65
// mocks to record events
@@ -369,4 +368,160 @@ describe('FormBuilder', () => {
369368
.map((error) => error.text());
370369
expect(errors).toEqual([]);
371370
});
371+
372+
it("should allow changing of Section's Display Name", () => {
373+
const uiSchema = {
374+
definitions: {
375+
full_names: {
376+
'ui:order': ['first_names', 'last_names'],
377+
},
378+
},
379+
user_full_names: {
380+
'ui:order': ['first_names', 'last_names'],
381+
},
382+
'ui:order': ['user_full_names'],
383+
};
384+
385+
const jsonSchema = {
386+
definitions: {
387+
full_names: {
388+
title: 'Full Names',
389+
type: 'object',
390+
description: 'This is a composite field',
391+
properties: {
392+
first_names: {
393+
title: 'First Names',
394+
type: 'string',
395+
},
396+
last_names: {
397+
title: 'Last Names',
398+
type: 'string',
399+
},
400+
},
401+
dependencies: {},
402+
required: [],
403+
},
404+
},
405+
properties: {
406+
user_full_names: {
407+
$ref: '#/definitions/full_names',
408+
title: 'User Full Names',
409+
description: 'Full names description',
410+
},
411+
},
412+
dependencies: {},
413+
required: [],
414+
type: 'object',
415+
};
416+
417+
const innerProps = {
418+
...props,
419+
schema: JSON.stringify(jsonSchema),
420+
uiSchema: JSON.stringify(uiSchema),
421+
};
422+
423+
const div = document.createElement('div');
424+
document.body.appendChild(div);
425+
const wrapper = mount(<FormBuilder {...innerProps} />, { attachTo: div });
426+
427+
const sectionHeadInputs = wrapper
428+
.find('.section-container')
429+
.first()
430+
.find('.section-head')
431+
.first()
432+
.find('input');
433+
434+
const titleInput = sectionHeadInputs.at(2);
435+
436+
titleInput.simulate('change', {
437+
target: {
438+
value: 'new title change',
439+
},
440+
});
441+
442+
const updatedSchema = JSON.parse(mockEvent.mock.calls[0][0]);
443+
444+
expect(updatedSchema.properties.user_full_names.title).toEqual(
445+
'new title change',
446+
);
447+
mockEvent.mockClear();
448+
});
449+
450+
it("should allow changing of a Section's Description", () => {
451+
const uiSchema = {
452+
definitions: {
453+
full_names: {
454+
'ui:order': ['first_names', 'last_names'],
455+
},
456+
},
457+
user_full_names: {
458+
'ui:order': ['first_names', 'last_names'],
459+
},
460+
'ui:order': ['user_full_names'],
461+
};
462+
463+
const jsonSchema = {
464+
definitions: {
465+
full_names: {
466+
title: 'Full Names',
467+
type: 'object',
468+
description: 'This is a composite field',
469+
properties: {
470+
first_names: {
471+
title: 'First Names',
472+
type: 'string',
473+
},
474+
last_names: {
475+
title: 'Last Names',
476+
type: 'string',
477+
},
478+
},
479+
dependencies: {},
480+
required: [],
481+
},
482+
},
483+
properties: {
484+
user_full_names: {
485+
$ref: '#/definitions/full_names',
486+
title: 'User Full Names',
487+
description: 'Full names description',
488+
},
489+
},
490+
dependencies: {},
491+
required: [],
492+
type: 'object',
493+
};
494+
495+
const innerProps = {
496+
...props,
497+
schema: JSON.stringify(jsonSchema),
498+
uiSchema: JSON.stringify(uiSchema),
499+
};
500+
501+
const div = document.createElement('div');
502+
document.body.appendChild(div);
503+
const wrapper = mount(<FormBuilder {...innerProps} />, { attachTo: div });
504+
505+
const sectionHeadInputs = wrapper
506+
.find('.section-container')
507+
.first()
508+
.find('.section-head')
509+
.first()
510+
.find('input');
511+
512+
const titleInput = sectionHeadInputs.at(3);
513+
514+
titleInput.simulate('change', {
515+
target: {
516+
value: 'new description change',
517+
},
518+
});
519+
520+
const updatedSchema = JSON.parse(mockEvent.mock.calls[0][0]);
521+
522+
expect(updatedSchema.properties.user_full_names.description).toEqual(
523+
'new description change',
524+
);
525+
mockEvent.mockClear();
526+
});
372527
});

src/formBuilder/Section.test.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import React from 'react';
21
import { mount } from 'enzyme';
2+
import React from 'react';
33
import DEFAULT_FORM_INPUTS from './defaults/defaultFormInputs';
44
import Section from './Section';
55

@@ -99,6 +99,20 @@ describe('Section', () => {
9999
mockEvent.mockClear();
100100
});
101101

102+
it('changes the section description', () => {
103+
const div = document.createElement('div');
104+
document.body.appendChild(div);
105+
const wrapper = mount(<Section {...props} />, { attachTo: div });
106+
const descriptionInput = wrapper.find('.card-text').at(3);
107+
descriptionInput.simulate('change', {
108+
target: { value: 'wow description change' },
109+
});
110+
expect(mockEvent.mock.calls).toEqual([
111+
[{ title: 'wow description change' }, {}],
112+
]);
113+
mockEvent.mockClear();
114+
});
115+
102116
it('adds components to the internal schema', () => {
103117
const div = document.createElement('div');
104118
document.body.appendChild(div);

src/formBuilder/utils.js

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
// @flow
2-
import * as React from 'react';
32
import type { Node } from 'react';
3+
import * as React from 'react';
44
import type {
55
CardBody,
66
CardProps,
7+
DataOptions,
8+
DataType,
79
ElementProps,
810
FormInput,
9-
Mods,
1011
ModalBody,
11-
DataOptions,
12-
DataType,
12+
Mods,
1313
} from './types';
1414

1515
// parse in either YAML or JSON
@@ -683,10 +683,18 @@ export function countElementsFromSchema(schemaData: any): number {
683683
// convert an element into a schema equivalent
684684
function generateSchemaElementFromElement(element: ElementProps) {
685685
if (element.$ref !== undefined) {
686+
const title =
687+
element.schema !== undefined && element.schema.title !== undefined
688+
? element.schema.title
689+
: element.dataOptions.title;
690+
const description =
691+
element.schema !== undefined && element.schema.description !== undefined
692+
? element.schema.description
693+
: element.dataOptions.description;
686694
return {
687695
$ref: element.$ref,
688-
title: element.dataOptions.title,
689-
description: element.dataOptions.description,
696+
title: title,
697+
description: description,
690698
};
691699
} else if (element.propType === 'card') {
692700
if (element.dataOptions.category === 'section') {

src/formBuilder/utils.test.js

Lines changed: 64 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,26 @@
1-
import React from 'react';
21
import { mount } from 'enzyme';
2+
import React from 'react';
33
import Card from './Card';
4+
import DEFAULT_FORM_INPUTS from './defaults/defaultFormInputs';
45
import Section from './Section';
56
import {
6-
parse,
7-
stringify,
8-
getCardCategory,
7+
addCardObj,
8+
addSectionObj,
99
checkForUnsupportedFeatures,
10+
DEFAULT_INPUT_NAME,
11+
excludeKeys,
12+
generateCategoryHash,
13+
generateElementComponentsFromSchemas,
1014
generateElementPropsFromSchemas,
1115
generateSchemaFromElementProps,
1216
generateUiSchemaFromElementProps,
13-
generateCategoryHash,
14-
generateElementComponentsFromSchemas,
15-
subtractArray,
16-
excludeKeys,
17+
getCardCategory,
1718
getNewElementDefaultDataOptions,
18-
addCardObj,
19-
addSectionObj,
20-
DEFAULT_INPUT_NAME,
2119
getRandomId,
20+
parse,
21+
stringify,
22+
subtractArray,
2223
} from './utils';
23-
import DEFAULT_FORM_INPUTS from './defaults/defaultFormInputs';
2424

2525
const schema = {
2626
type: 'object',
@@ -475,6 +475,58 @@ describe('generateSchemaFromElementProps', () => {
475475
),
476476
).toThrow(new Error('Element that is neither card, section, nor ref'));
477477
});
478+
479+
it('generates schema from element with schema prop', () => {
480+
const expectedSchemaElement = {
481+
$ref: '#/definitions/someDefinition',
482+
title: 'Input Field',
483+
description: 'This is an example description',
484+
};
485+
486+
const result = generateSchemaFromElementProps(
487+
[
488+
{
489+
name: 'exampleCard',
490+
required: true,
491+
$ref: '#/definitions/someDefinition',
492+
schema: {
493+
description: 'This is an example description',
494+
title: 'Input Field',
495+
},
496+
propType: 'card',
497+
},
498+
],
499+
DEFAULT_FORM_INPUTS,
500+
);
501+
502+
expect(result.properties.exampleCard).toEqual(expectedSchemaElement);
503+
});
504+
505+
it('generates schema from element with dataOptions prop', () => {
506+
const expectedSchemaElement = {
507+
$ref: '#/definitions/someDefinition',
508+
title: 'Input Field',
509+
description: 'This is an example description',
510+
};
511+
512+
const result = generateSchemaFromElementProps(
513+
[
514+
{
515+
name: 'exampleCard',
516+
required: true,
517+
$ref: '#/definitions/someDefinition',
518+
dataOptions: {
519+
description: 'This is an example description',
520+
title: 'Input Field',
521+
},
522+
propType: 'card',
523+
},
524+
],
525+
DEFAULT_FORM_INPUTS,
526+
);
527+
528+
expect(result.properties.exampleCard).toEqual(expectedSchemaElement);
529+
});
478530
});
479531

480532
describe('generateUiSchemaFromElementProps', () => {

0 commit comments

Comments
 (0)