feat: support examples in object schema

This commit is contained in:
Oprysk 2021-12-14 12:00:22 +02:00
parent 6c41e95aa0
commit 5f618c2979
5 changed files with 48 additions and 44 deletions

View File

@ -29,7 +29,7 @@ export interface FieldProps extends SchemaOptions {
} }
@observer @observer
export class Field extends React.Component<FieldProps> { export class Field extends React.PureComponent<FieldProps> {
toggle = () => { toggle = () => {
if (this.props.field.expanded === undefined && this.props.expandByDefault) { if (this.props.field.expanded === undefined && this.props.expandByDefault) {
this.props.field.expanded = false; this.props.field.expanded = false;

View File

@ -18,37 +18,35 @@ export interface ObjectSchemaProps extends SchemaProps {
}; };
} }
@observer export const ObjectSchemaComponent = observer(
export class ObjectSchema extends React.Component<ObjectSchemaProps> { ({
static contextType = OptionsContext; schema: { fields = [], title },
showTitle,
discriminator,
skipReadOnly,
skipWriteOnly,
}: ObjectSchemaProps) => {
const { expandSingleSchemaField, showObjectExample } = React.useContext(OptionsContext);
get parentSchema() { const filteredFields = React.useMemo(
return this.props.discriminator!.parentSchema; () =>
} skipReadOnly || skipWriteOnly
? fields.filter(
item =>
!(
(skipReadOnly && item.schema.readOnly) ||
(skipWriteOnly && item.schema.writeOnly)
),
)
: fields,
[skipReadOnly, skipWriteOnly, fields],
);
render() { const expandByDefault = expandSingleSchemaField && filteredFields.length === 1;
const {
schema: { fields = [] },
showTitle,
discriminator,
} = this.props;
const needFilter = this.props.skipReadOnly || this.props.skipWriteOnly;
const filteredFields = needFilter
? fields.filter(item => {
return !(
(this.props.skipReadOnly && item.schema.readOnly) ||
(this.props.skipWriteOnly && item.schema.writeOnly)
);
})
: fields;
const expandByDefault = this.context.expandSingleSchemaField && filteredFields.length === 1;
return ( return (
<PropertiesTable> <PropertiesTable>
{showTitle && <PropertiesTableCaption>{this.props.schema.title}</PropertiesTableCaption>} {showTitle && <PropertiesTableCaption>{title}</PropertiesTableCaption>}
<tbody> <tbody>
{mapWithLast(filteredFields, (field, isLast) => { {mapWithLast(filteredFields, (field, isLast) => {
return ( return (
@ -58,26 +56,27 @@ export class ObjectSchema extends React.Component<ObjectSchemaProps> {
field={field} field={field}
expandByDefault={expandByDefault} expandByDefault={expandByDefault}
renderDiscriminatorSwitch={ renderDiscriminatorSwitch={
(discriminator && discriminator?.fieldName === field.name
discriminator.fieldName === field.name && ? () => (
(() => ( <DiscriminatorDropdown
<DiscriminatorDropdown parent={discriminator!.parentSchema}
parent={this.parentSchema} enumValues={field.schema.enum}
enumValues={field.schema.enum} />
/> )
))) || : undefined
undefined
} }
className={field.expanded ? 'expanded' : undefined} className={field.expanded ? 'expanded' : undefined}
showExamples={false} showExamples={showObjectExample}
skipReadOnly={this.props.skipReadOnly} skipReadOnly={skipReadOnly}
skipWriteOnly={this.props.skipWriteOnly} skipWriteOnly={skipWriteOnly}
showTitle={this.props.showTitle} showTitle={showTitle}
/> />
); );
})} })}
</tbody> </tbody>
</PropertiesTable> </PropertiesTable>
); );
} },
} );
export const ObjectSchema = React.memo<ObjectSchemaProps>(ObjectSchemaComponent);

View File

@ -7,7 +7,7 @@ import * as React from 'react';
import { filterPropsDeep } from '../../utils/test-utils'; import { filterPropsDeep } from '../../utils/test-utils';
import { ObjectSchema, Schema } from '../'; import { ObjectSchemaComponent, ObjectSchema, Schema } from '../';
import { OpenAPIParser, SchemaModel } from '../../services'; import { OpenAPIParser, SchemaModel } from '../../services';
import { RedocNormalizedOptions } from '../../services/RedocNormalizedOptions'; import { RedocNormalizedOptions } from '../../services/RedocNormalizedOptions';
import * as simpleDiscriminatorFixture from './fixtures/simple-discriminator.json'; import * as simpleDiscriminatorFixture from './fixtures/simple-discriminator.json';
@ -26,7 +26,7 @@ describe('Components', () => {
options, options,
); );
const schemaViewElement = shallow(<Schema schema={schema} />).getElement(); const schemaViewElement = shallow(<Schema schema={schema} />).getElement();
expect(schemaViewElement.type).toEqual(ObjectSchema); expect(schemaViewElement.type).toEqual(ObjectSchemaComponent);
expect(schemaViewElement.props.discriminator).toBeDefined(); expect(schemaViewElement.props.discriminator).toBeDefined();
expect(schemaViewElement.props.discriminator.parentSchema).toBeDefined(); expect(schemaViewElement.props.discriminator.parentSchema).toBeDefined();
expect(schemaViewElement.props.discriminator.fieldName).toEqual('type'); expect(schemaViewElement.props.discriminator.fieldName).toEqual('type');

View File

@ -4,6 +4,7 @@ exports[`Components SchemaView discriminator should correctly render discriminat
<styled.table> <styled.table>
<tbody> <tbody>
<Field <Field
expandByDefault={false}
field={ field={
FieldModel { FieldModel {
"const": "", "const": "",
@ -59,6 +60,7 @@ exports[`Components SchemaView discriminator should correctly render discriminat
showExamples={false} showExamples={false}
/> />
<Field <Field
expandByDefault={false}
field={ field={
FieldModel { FieldModel {
"const": "", "const": "",

View File

@ -35,6 +35,7 @@ export interface RedocRawOptions {
simpleOneOfTypeLabel?: boolean | string; simpleOneOfTypeLabel?: boolean | string;
payloadSampleIdx?: number; payloadSampleIdx?: number;
expandSingleSchemaField?: boolean | string; expandSingleSchemaField?: boolean | string;
showObjectExample?: boolean | string;
unstable_ignoreMimeParameters?: boolean; unstable_ignoreMimeParameters?: boolean;
@ -220,6 +221,7 @@ export class RedocNormalizedOptions {
simpleOneOfTypeLabel: boolean; simpleOneOfTypeLabel: boolean;
payloadSampleIdx: number; payloadSampleIdx: number;
expandSingleSchemaField: boolean; expandSingleSchemaField: boolean;
showObjectExample: boolean;
/* tslint:disable-next-line */ /* tslint:disable-next-line */
unstable_ignoreMimeParameters: boolean; unstable_ignoreMimeParameters: boolean;
@ -281,6 +283,7 @@ export class RedocNormalizedOptions {
this.simpleOneOfTypeLabel = argValueToBoolean(raw.simpleOneOfTypeLabel); this.simpleOneOfTypeLabel = argValueToBoolean(raw.simpleOneOfTypeLabel);
this.payloadSampleIdx = RedocNormalizedOptions.normalizePayloadSampleIdx(raw.payloadSampleIdx); this.payloadSampleIdx = RedocNormalizedOptions.normalizePayloadSampleIdx(raw.payloadSampleIdx);
this.expandSingleSchemaField = argValueToBoolean(raw.expandSingleSchemaField); this.expandSingleSchemaField = argValueToBoolean(raw.expandSingleSchemaField);
this.showObjectExample = argValueToBoolean(raw.showObjectExample);
this.unstable_ignoreMimeParameters = argValueToBoolean(raw.unstable_ignoreMimeParameters); this.unstable_ignoreMimeParameters = argValueToBoolean(raw.unstable_ignoreMimeParameters);