Skip to content

Commit 6e2eeee

Browse files
authored
feat: Add more property labels and render complex objects (#133)
1 parent aaaf529 commit 6e2eeee

File tree

3 files changed

+168
-23
lines changed

3 files changed

+168
-23
lines changed

library/src/containers/Schemas/Schema.tsx

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,20 @@ const renderSchemaProps = (
2828
): React.ReactNode => {
2929
const properties = schema.properties;
3030

31-
if (!properties) {
32-
return (
33-
<SchemaProperties name={schemaName} properties={schema} treeSpace={0} />
34-
);
31+
if (properties) {
32+
return Object.entries(properties).map(([key, prop]) => (
33+
<SchemaProperties key={key} name={key} properties={prop} treeSpace={0} />
34+
));
3535
}
3636

37-
return Object.entries(properties).map(([key, prop]) => (
38-
<SchemaProperties key={key} name={key} properties={prop} treeSpace={0} />
39-
));
37+
return (
38+
<SchemaProperties
39+
name={schemaName}
40+
hasDynamicName
41+
properties={schema}
42+
treeSpace={0}
43+
/>
44+
);
4045
};
4146

4247
export const SchemaComponent: React.FunctionComponent<Props> = ({
@@ -68,10 +73,6 @@ export const SchemaComponent: React.FunctionComponent<Props> = ({
6873
<>
6974
<div className={`${bemClasses.element(`${className}-table`)} p-4`}>
7075
{renderSchemaProps(name, schema)}
71-
<div className={bemClasses.element('additional-properties-notice')}>
72-
Additional properties are{' '}
73-
{schema.additionalProperties === false && 'NOT'} allowed.
74-
</div>
7576
</div>
7677
{/* we need to disable this component if schema has "not" field anywhere in it */}
7778
{hasNotField ? null : (

library/src/containers/Schemas/SchemaProperties.tsx

Lines changed: 140 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,29 @@ const renderProperties = (
6969
));
7070
};
7171

72+
const renderAdditionalProperties = (
73+
schema: Schema,
74+
treeSpace: number,
75+
): React.ReactNode => {
76+
const additionalProperties = schema.additionalProperties;
77+
78+
if (!additionalProperties || typeof additionalProperties === 'boolean') {
79+
return null;
80+
}
81+
82+
return (
83+
<div>
84+
<SchemaPropertiesComponent
85+
key="property-name"
86+
name="(property name)"
87+
hasDynamicName
88+
properties={additionalProperties as Schema}
89+
treeSpace={treeSpace}
90+
/>
91+
</div>
92+
);
93+
};
94+
7295
const renderOf = (treeSpace: number, schemas?: Schema[]): React.ReactNode => {
7396
if (!schemas) {
7497
return null;
@@ -90,6 +113,7 @@ const renderOf = (treeSpace: number, schemas?: Schema[]): React.ReactNode => {
90113

91114
interface Props {
92115
name: string;
116+
hasDynamicName?: boolean;
93117
properties: Schema;
94118
treeSpace: number;
95119
description?: React.ReactNode;
@@ -130,6 +154,7 @@ const renderPropertyDescription = (el: SchemaElement): React.ReactNode => {
130154

131155
export const SchemaPropertiesComponent: React.FunctionComponent<Props> = ({
132156
name,
157+
hasDynamicName = false,
133158
properties,
134159
treeSpace,
135160
}) => {
@@ -146,7 +171,9 @@ export const SchemaPropertiesComponent: React.FunctionComponent<Props> = ({
146171
return (
147172
<div>
148173
<div className="flex py-2">
149-
<div className="flex-1">{renderPropertyName(element)}</div>
174+
<div className={`flex-1 ${hasDynamicName && 'font-italic'}`}>
175+
{renderPropertyName(element)}
176+
</div>
150177
<div className="flex-1">
151178
<span className="capitalize text-sm text-teal font-bold">
152179
{element.schema.content.type}
@@ -176,12 +203,124 @@ export const SchemaPropertiesComponent: React.FunctionComponent<Props> = ({
176203
must match {element.schema.content.pattern}
177204
</span>
178205
)}
206+
{element.schema.content.uniqueItems && (
207+
<span
208+
className="bg-red-700 font-bold no-underline text-white rounded lowercase ml-2"
209+
style={{ height: '20px', fontSize: '11px', padding: '3px' }}
210+
>
211+
Unique
212+
</span>
213+
)}
214+
{element.schema.content.minItems && (
215+
<span
216+
className="bg-purple-dark font-bold no-underline text-white rounded lowercase ml-2"
217+
style={{ height: '20px', fontSize: '11px', padding: '3px' }}
218+
title={`At least ${element.schema.content.minItems} items`}
219+
>
220+
&gt;= {element.schema.content.minItems} items
221+
</span>
222+
)}
223+
{element.schema.content.maxItems && (
224+
<span
225+
className="bg-purple-dark font-bold no-underline text-white rounded lowercase ml-2"
226+
style={{ height: '20px', fontSize: '11px', padding: '3px' }}
227+
title={`At most ${element.schema.content.maxItems} items`}
228+
>
229+
&lt;= {element.schema.content.maxItems} items
230+
</span>
231+
)}
232+
{element.schema.content.minLength && (
233+
<span
234+
className="bg-purple-dark font-bold no-underline text-white rounded lowercase ml-2"
235+
style={{ height: '20px', fontSize: '11px', padding: '3px' }}
236+
title={`At least ${element.schema.content.minLength} characters long`}
237+
>
238+
length &gt;= {element.schema.content.minLength}
239+
</span>
240+
)}
241+
{element.schema.content.maxLength && (
242+
<span
243+
className="bg-purple-dark font-bold no-underline text-white rounded lowercase ml-2"
244+
style={{ height: '20px', fontSize: '11px', padding: '3px' }}
245+
title={`At most ${element.schema.content.maxLength} characters long`}
246+
>
247+
length &lt;= {element.schema.content.maxLength}
248+
</span>
249+
)}
250+
{element.schema.content.minimum && (
251+
<span
252+
className="bg-purple-dark font-bold no-underline text-white rounded lowercase ml-2"
253+
style={{ height: '20px', fontSize: '11px', padding: '3px' }}
254+
title={`At least ${element.schema.content.minimum}`}
255+
>
256+
&gt;= {element.schema.content.minimum}
257+
</span>
258+
)}
259+
{element.schema.content.maximum && (
260+
<span
261+
className="bg-purple-dark font-bold no-underline text-white rounded lowercase ml-2"
262+
style={{ height: '20px', fontSize: '11px', padding: '3px' }}
263+
title={`At most ${element.schema.content.maximum}`}
264+
>
265+
&lt;= {element.schema.content.maximum}
266+
</span>
267+
)}
268+
{element.schema.content.exclusiveMinimum && (
269+
<span
270+
className="bg-purple-dark font-bold no-underline text-white rounded lowercase ml-2"
271+
style={{ height: '20px', fontSize: '11px', padding: '3px' }}
272+
title={`Greater than ${element.schema.content.exclusiveMinimum}`}
273+
>
274+
&gt; {element.schema.content.exclusiveMinimum}
275+
</span>
276+
)}
277+
{element.schema.content.exclusiveMaximum && (
278+
<span
279+
className="bg-purple-dark font-bold no-underline text-white rounded lowercase ml-2"
280+
style={{ height: '20px', fontSize: '11px', padding: '3px' }}
281+
title={`Less than ${element.schema.content.exclusiveMaximum}`}
282+
>
283+
&lt; {element.schema.content.exclusiveMaximum}
284+
</span>
285+
)}
179286
<div className="py-2">{renderPropertyDescription(element)}</div>
287+
{element.schema.content.type === 'object' && (
288+
<div className="font-italic text-gray-600 text-sm">
289+
{(!element.schema.content.additionalProperties ||
290+
typeof element.schema.content.additionalProperties ===
291+
'boolean') && (
292+
<p className="my-0">
293+
Additional properties are{' '}
294+
{element.schema.content.additionalProperties === false &&
295+
'NOT'}{' '}
296+
allowed.
297+
</p>
298+
)}
299+
{element.schema.content.additionalProperties &&
300+
typeof element.schema.content.additionalProperties ===
301+
'object' && (
302+
<p className="my-0">
303+
Additional properties must adhere to the following schema.
304+
</p>
305+
)}
306+
</div>
307+
)}
308+
{element.schema.content.items && (
309+
<div className="font-italic text-gray-600 text-sm">
310+
{element.schema.content.items &&
311+
typeof element.schema.content.items === 'object' && (
312+
<p className="my-0">
313+
Array items must adhere to the following schema.
314+
</p>
315+
)}
316+
</div>
317+
)}
180318
</div>
181319
</div>
182320
{renderOf(space, alteredProperties.anyOf)}
183321
{renderOf(space, alteredProperties.oneOf)}
184322
{renderProperties(alteredProperties, space)}
323+
{renderAdditionalProperties(alteredProperties, space)}
185324
{renderItems(alteredProperties, space)}
186325
</div>
187326
);

library/src/styles/fiori.css

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
.font-bold {
2323
font-weight: 700;
2424
}
25+
.font-italic {
26+
font-style: italic;
27+
}
2528
.px-2 {
2629
padding-left: 0.5rem;
2730
padding-right: 0.5rem;
@@ -71,6 +74,16 @@
7174
.text-white {
7275
color: #fff;
7376
}
77+
.text-gray-600 {
78+
color: #718096;
79+
}
80+
.text-sm {
81+
font-size: 0.875rem;
82+
}
83+
.my-0 {
84+
margin-top: 0;
85+
margin-bottom: 0;
86+
}
7487
.ml-2 {
7588
margin-left: 0.5rem;
7689
}
@@ -83,6 +96,9 @@
8396
.bg-purple-dark {
8497
background-color: #794acf;
8598
}
99+
.bg-red-700 {
100+
background-color: #c53030;
101+
}
86102

87103
/* CURRENT THEME BASED ON KYMA STYLES */
88104

@@ -1344,14 +1360,3 @@
13441360
padding: 0 0.5rem;
13451361
color: #f6993f;
13461362
}
1347-
1348-
.asyncapi__additional-properties-notice {
1349-
text-align: center;
1350-
font-style: italic;
1351-
font-weight: bold;
1352-
color: #333333;
1353-
font-size: 0.75rem;
1354-
line-height: 2;
1355-
margin-right: 0.5rem;
1356-
margin-top: 0.5rem;
1357-
}

0 commit comments

Comments
 (0)