Skip to content

Commit c829850

Browse files
fix: oneOf included when inside of arrays (#927)
Co-authored-by: Lukasz Gornicki <[email protected]>
1 parent 82aa366 commit c829850

File tree

2 files changed

+77
-8
lines changed

2 files changed

+77
-8
lines changed

library/src/components/Schema.tsx

+21-8
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ interface Props {
1414
dependentRequired?: string[];
1515
expanded?: boolean;
1616
onlyTitle?: boolean;
17+
isArray?: boolean;
1718
}
1819

1920
const SchemaContext = React.createContext({
@@ -31,17 +32,22 @@ export const Schema: React.FunctionComponent<Props> = ({
3132
dependentRequired,
3233
expanded: propExpanded = false,
3334
onlyTitle = false,
35+
isArray = false,
3436
}) => {
3537
const { reverse, deepExpanded } = useContext(SchemaContext);
36-
const [expanded, setExpanded] = useState(propExpanded);
38+
const [expanded, setExpanded] = useState(propExpanded || isArray);
3739
const [deepExpand, setDeepExpand] = useState(false);
3840

3941
useEffect(() => {
40-
setDeepExpand(deepExpanded);
42+
if (!isArray) {
43+
setDeepExpand(deepExpanded);
44+
}
4145
}, [deepExpanded, setDeepExpand]);
4246

4347
useEffect(() => {
44-
setExpanded(deepExpand);
48+
if (!isArray) {
49+
setExpanded(deepExpand);
50+
}
4551
}, [deepExpand, setExpanded]);
4652

4753
if (
@@ -88,7 +94,7 @@ export const Schema: React.FunctionComponent<Props> = ({
8894
<div>
8995
<div className="flex py-2">
9096
<div className={`${onlyTitle ? '' : 'min-w-1/4'} mr-2`}>
91-
{isExpandable && !isCircular ? (
97+
{isExpandable && !isCircular && !isArray ? (
9298
<>
9399
<CollapseButton
94100
onClick={() => setExpanded(prev => !prev)}
@@ -270,7 +276,7 @@ export const Schema: React.FunctionComponent<Props> = ({
270276
reverse ? 'bg-gray-200' : ''
271277
} ${expanded ? 'block' : 'hidden'}`}
272278
>
273-
<SchemaProperties schema={schema} />
279+
<SchemaProperties schema={schema} isArray={isArray} />
274280
<SchemaItems schema={schema} />
275281

276282
{schema.oneOf() &&
@@ -368,10 +374,12 @@ export const Schema: React.FunctionComponent<Props> = ({
368374

369375
interface SchemaPropertiesProps {
370376
schema: SchemaInterface;
377+
isArray: boolean;
371378
}
372379

373380
const SchemaProperties: React.FunctionComponent<SchemaPropertiesProps> = ({
374381
schema,
382+
isArray,
375383
}) => {
376384
const properties = schema.properties();
377385
if (properties === undefined || !Object.keys(properties)) {
@@ -471,17 +479,22 @@ const SchemaItems: React.FunctionComponent<SchemaItemsProps> = ({ schema }) => {
471479
!Array.isArray(items) &&
472480
Object.keys(items.properties() || {}).length
473481
) {
474-
return <SchemaProperties schema={items} />;
482+
return <Schema schema={items} isArray={true} />;
475483
} else if (Array.isArray(items)) {
476484
return (
477485
<>
478486
{items.map((item, idx) => (
479-
<Schema schema={item} schemaName={`${idx + 1} item:`} key={idx} />
487+
<Schema
488+
schema={item}
489+
isArray={true}
490+
schemaName={`${idx + 1} item:`}
491+
key={idx}
492+
/>
480493
))}
481494
</>
482495
);
483496
}
484-
return <Schema schema={items} schemaName="Items:" />;
497+
return <Schema schema={items} isArray={true} schemaName="Items:" />;
485498
};
486499

487500
interface AdditionalItemsProps {

library/src/components/__tests__/Schema.test.tsx

+56
Original file line numberDiff line numberDiff line change
@@ -93,4 +93,60 @@ describe('Schema component', () => {
9393
expect(screen.getByText('false')).toBeDefined();
9494
});
9595
});
96+
97+
describe('should render arrays', () => {
98+
test('which includes oneOf', async () => {
99+
const schemaModel = new SchemaModel({
100+
title: 'Sets',
101+
type: 'array',
102+
items: {
103+
title: 'Set',
104+
type: 'object',
105+
properties: {
106+
pets: {
107+
title: 'Pets',
108+
type: 'array',
109+
items: {
110+
title: 'Pet',
111+
type: 'object',
112+
discriminator: 'type',
113+
properties: {
114+
type: {
115+
title: 'Pet.Type',
116+
type: 'string',
117+
enum: ['CAT', 'DOG'],
118+
},
119+
},
120+
oneOf: [
121+
{
122+
title: 'Cat',
123+
type: 'object',
124+
properties: {
125+
type: {
126+
const: 'CAT',
127+
},
128+
},
129+
},
130+
{
131+
title: 'Dog',
132+
type: 'object',
133+
properties: {
134+
type: {
135+
const: 'DOG',
136+
},
137+
},
138+
},
139+
],
140+
},
141+
},
142+
},
143+
},
144+
});
145+
146+
render(<Schema schema={schemaModel} />);
147+
148+
expect(screen.getByText('Adheres to Cat:')).toBeDefined();
149+
expect(screen.getByText('Or to Dog:')).toBeDefined();
150+
});
151+
});
96152
});

0 commit comments

Comments
 (0)