Skip to content

Commit 2bf9bcf

Browse files
authored
Fix React Material category filtering
Previously the React Material categories were filtered visually but not in the util functions. This could lead to the wrong content being shown for a category. Includes testcases. Fixes #1777 Signed-off-by: Max Elia Schweigkofler <max_elia@hotmail.de>
1 parent 81e4dd6 commit 2bf9bcf

File tree

4 files changed

+154
-8
lines changed

4 files changed

+154
-8
lines changed

packages/material/src/layouts/MaterialCategorizationLayout.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,11 @@ export const MaterialCategorizationLayoutRenderer = (props: MaterialCategorizati
9292
} = props;
9393
const categorization = uischema as Categorization;
9494
const [activeCategory, setActiveCategory]= useState<number|undefined>(selected??0);
95+
const categories = categorization.elements.filter((category: Category) =>
96+
isVisible(category, data, undefined, ajv)
97+
);
9598
const childProps: MaterialLayoutRendererProps = {
96-
elements: categorization.elements[activeCategory].elements,
99+
elements: categories[activeCategory].elements,
97100
schema,
98101
path,
99102
direction: 'column',
@@ -102,9 +105,6 @@ export const MaterialCategorizationLayoutRenderer = (props: MaterialCategorizati
102105
renderers,
103106
cells
104107
};
105-
const categories = categorization.elements.filter((category: Category) =>
106-
isVisible(category, data, undefined, ajv)
107-
);
108108
const onTabChange = (_event: any, value: any) => {
109109
if (onChange) {
110110
onChange(value, activeCategory);

packages/material/src/layouts/MaterialCategorizationStepperLayout.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,18 +94,18 @@ export const MaterialCategorizationStepperLayoutRenderer = (props: MaterialCateg
9494
const buttonStyle = {
9595
marginRight: '1em'
9696
};
97+
const categories = categorization.elements.filter((category: Category) =>
98+
isVisible(category, data, undefined, ajv)
99+
);
97100
const childProps: MaterialLayoutRendererProps = {
98-
elements: categorization.elements[activeCategory].elements,
101+
elements: categories[activeCategory].elements,
99102
schema,
100103
path,
101104
direction: 'column',
102105
visible,
103106
renderers,
104107
cells
105108
};
106-
const categories = categorization.elements.filter((category: Category) =>
107-
isVisible(category, data, undefined, ajv)
108-
);
109109
return (
110110
<Hidden xsUp={!visible}>
111111
<Stepper activeStep={activeCategory} nonLinear>

packages/material/test/renderers/MaterialCategorizationLayout.test.tsx

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,4 +372,77 @@ describe('Material categorization layout', () => {
372372
const materialArrayLayout = wrapper.find(MaterialLayoutRenderer);
373373
expect(materialArrayLayout.props().renderers).toHaveLength(0);
374374
});
375+
376+
it('display correct content when hiding a tab', () => {
377+
const data = { name : 'fo' };
378+
const condition: SchemaBasedCondition = {
379+
scope: '#/properties/name',
380+
schema: { maxLength: 3 }
381+
};
382+
const nameControl: ControlElement = {
383+
type: 'Control',
384+
scope: '#/properties/name'
385+
};
386+
const uischema: Categorization = {
387+
type: 'Categorization',
388+
label: '',
389+
options: {
390+
showNavButtons: true
391+
},
392+
elements: [
393+
{
394+
type: 'Category',
395+
label: 'A',
396+
elements: undefined
397+
},
398+
{
399+
type: 'Category',
400+
label: 'B',
401+
elements: undefined,
402+
rule: {
403+
effect: RuleEffect.SHOW,
404+
condition: condition
405+
}
406+
},
407+
{
408+
type: 'Category',
409+
label: 'C',
410+
elements: [nameControl],
411+
rule: {
412+
effect: RuleEffect.HIDE,
413+
condition: condition
414+
}
415+
}
416+
]
417+
};
418+
419+
const core = initCore(fixture.schema, uischema, data);
420+
421+
const wrapper = mount(
422+
<JsonFormsStateProvider initState={{ renderers: materialRenderers, core }}>
423+
<MaterialCategorizationLayoutRenderer
424+
{...layoutDefaultProps}
425+
schema={fixture.schema}
426+
uischema={uischema}
427+
/>
428+
</JsonFormsStateProvider>
429+
);
430+
431+
wrapper
432+
.find(Tab)
433+
.at(1)
434+
.simulate('click');
435+
436+
let isCategoryCshown = wrapper.find('input[type="text"]').length > 0;
437+
expect(isCategoryCshown).toBe(false);
438+
439+
core.data = { ...core.data, name: 'Barr' };
440+
wrapper.setProps({ initState: { renderers: materialRenderers, core }} );
441+
wrapper.update();
442+
443+
isCategoryCshown = wrapper.find('input[type="text"]').length > 0;
444+
expect(isCategoryCshown).toBe(true);
445+
446+
wrapper.unmount();
447+
});
375448
});

packages/material/test/renderers/MaterialCategorizationStepperLayout.test.tsx

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -561,4 +561,77 @@ describe('Material categorization stepper layout', () => {
561561

562562
wrapper.unmount();
563563
});
564+
565+
it('display correct content when hiding a step', () => {
566+
const data = { name : 'fo' };
567+
const condition: SchemaBasedCondition = {
568+
scope: '#/properties/name',
569+
schema: { maxLength: 3 }
570+
};
571+
const nameControl: ControlElement = {
572+
type: 'Control',
573+
scope: '#/properties/name'
574+
};
575+
const uischema: Categorization = {
576+
type: 'Categorization',
577+
label: '',
578+
options: {
579+
showNavButtons: true
580+
},
581+
elements: [
582+
{
583+
type: 'Category',
584+
label: 'A',
585+
elements: undefined
586+
},
587+
{
588+
type: 'Category',
589+
label: 'B',
590+
elements: undefined,
591+
rule: {
592+
effect: RuleEffect.SHOW,
593+
condition: condition
594+
}
595+
},
596+
{
597+
type: 'Category',
598+
label: 'C',
599+
elements: [nameControl],
600+
rule: {
601+
effect: RuleEffect.HIDE,
602+
condition: condition
603+
}
604+
}
605+
]
606+
};
607+
608+
const core = initCore(fixture.schema, uischema, data);
609+
610+
const wrapper = mount(
611+
<JsonFormsStateProvider initState={{ renderers: materialRenderers, core }}>
612+
<MaterialCategorizationStepperLayoutRenderer
613+
{...layoutDefaultProps}
614+
schema={fixture.schema}
615+
uischema={uischema}
616+
/>
617+
</JsonFormsStateProvider>
618+
);
619+
620+
wrapper
621+
.find(StepButton)
622+
.at(1)
623+
.simulate('click');
624+
625+
let isCategoryCshown = wrapper.find('input[type="text"]').length > 0;
626+
expect(isCategoryCshown).toBe(false);
627+
628+
core.data = { ...core.data, name: 'Barr' };
629+
wrapper.setProps({ initState: { renderers: materialRenderers, core }} );
630+
wrapper.update();
631+
632+
isCategoryCshown = wrapper.find('input[type="text"]').length > 0;
633+
expect(isCategoryCshown).toBe(true);
634+
635+
wrapper.unmount();
636+
});
564637
});

0 commit comments

Comments
 (0)