feat: Add options expandAllFields hideShelfIcon hideHttpVerbs

This commit is contained in:
Till Kolter 2020-08-22 14:36:56 +02:00
parent d78e0a3fbf
commit 1d56ee70aa
7 changed files with 49 additions and 11 deletions

View File

@ -26,7 +26,15 @@ const specUrl =
(userUrl && userUrl[1]) || (swagger ? 'swagger.yaml' : big ? 'big-openapi.json' : 'openapi.yaml'); (userUrl && userUrl[1]) || (swagger ? 'swagger.yaml' : big ? 'big-openapi.json' : 'openapi.yaml');
let store; let store;
const options: RedocRawOptions = { nativeScrollbars: false, maxDisplayedEnumValues: 3 }; const options: RedocRawOptions = {
nativeScrollbars: false,
maxDisplayedEnumValues: 3,
expandAllSchemaFields: true,
hideShelfIcon: true,
hideHttpVerbs: true
};
console.log('options', options)
async function init() { async function init() {
const spec = await loadAndBundleSpec(specUrl); const spec = await loadAndBundleSpec(specUrl);

View File

@ -24,6 +24,7 @@ export interface FieldProps extends SchemaOptions {
field: FieldModel; field: FieldModel;
expandByDefault?: boolean; expandByDefault?: boolean;
expandAllFields?: boolean;
renderDiscriminatorSwitch?: (opts: FieldProps) => JSX.Element; renderDiscriminatorSwitch?: (opts: FieldProps) => JSX.Element;
} }
@ -31,7 +32,11 @@ export interface FieldProps extends SchemaOptions {
@observer @observer
export class Field extends React.Component<FieldProps> { export class Field extends React.Component<FieldProps> {
toggle = () => { toggle = () => {
if (this.props.field.expanded === undefined && this.props.expandByDefault) { if (
this.props.field.expanded === undefined &&
!this.props.field.expandAll &&
this.props.expandByDefault
) {
this.props.field.expanded = false; this.props.field.expanded = false;
} else { } else {
this.props.field.toggle(); this.props.field.toggle();
@ -46,11 +51,13 @@ export class Field extends React.Component<FieldProps> {
}; };
render() { render() {
const { className, field, isLast, expandByDefault } = this.props; const { className, field, isLast, expandByDefault, expandAllFields } = this.props;
const { name, deprecated, required, kind } = field; const { name, deprecated, required, kind } = field;
const withSubSchema = !field.schema.isPrimitive && !field.schema.isCircular; const withSubSchema = !field.schema.isPrimitive && !field.schema.isCircular;
const expanded = field.expanded === undefined ? expandByDefault : field.expanded; const expandChildren = field.expandAll === undefined ? expandAllFields : field.expandAll;
const expanded =
field.expanded === undefined ? expandChildren || expandByDefault : field.expanded;
const paramName = withSubSchema ? ( const paramName = withSubSchema ? (
<ClickablePropertyNameCell <ClickablePropertyNameCell
@ -90,6 +97,7 @@ export class Field extends React.Component<FieldProps> {
<PropertyCellWithInner colSpan={2}> <PropertyCellWithInner colSpan={2}>
<InnerPropertiesWrap> <InnerPropertiesWrap>
<Schema <Schema
expandAllFields={expandAllFields}
schema={field.schema} schema={field.schema}
skipReadOnly={this.props.skipReadOnly} skipReadOnly={this.props.skipReadOnly}
skipWriteOnly={this.props.skipWriteOnly} skipWriteOnly={this.props.skipWriteOnly}

View File

@ -45,6 +45,7 @@ export class ObjectSchema extends React.Component<ObjectSchemaProps> {
: fields; : fields;
const expandByDefault = this.context.expandSingleSchemaField && filteredFields.length === 1; const expandByDefault = this.context.expandSingleSchemaField && filteredFields.length === 1;
const expandAllFields = this.context.expandAllSchemaFields;
return ( return (
<PropertiesTable> <PropertiesTable>
@ -57,6 +58,7 @@ export class ObjectSchema extends React.Component<ObjectSchemaProps> {
isLast={isLast} isLast={isLast}
field={field} field={field}
expandByDefault={expandByDefault} expandByDefault={expandByDefault}
expandAllFields={expandAllFields}
renderDiscriminatorSwitch={ renderDiscriminatorSwitch={
(discriminator && (discriminator &&
discriminator.fieldName === field.name && discriminator.fieldName === field.name &&

View File

@ -13,6 +13,7 @@ import { OneOfSchema } from './OneOfSchema';
import { l } from '../../services/Labels'; import { l } from '../../services/Labels';
export interface SchemaOptions { export interface SchemaOptions {
expandAllFields?: boolean | string
showTitle?: boolean; showTitle?: boolean;
skipReadOnly?: boolean; skipReadOnly?: boolean;
skipWriteOnly?: boolean; skipWriteOnly?: boolean;

View File

@ -8,6 +8,7 @@ import { shortenHTTPVerb } from '../../utils/openapi';
import { MenuItems } from './MenuItems'; import { MenuItems } from './MenuItems';
import { MenuItemLabel, MenuItemLi, MenuItemTitle, OperationBadge } from './styled.elements'; import { MenuItemLabel, MenuItemLi, MenuItemTitle, OperationBadge } from './styled.elements';
import { l } from '../../services/Labels'; import { l } from '../../services/Labels';
import { OptionsContext } from '../OptionsProvider';
export interface MenuItemProps { export interface MenuItemProps {
item: IMenuItem; item: IMenuItem;
@ -17,6 +18,8 @@ export interface MenuItemProps {
@observer @observer
export class MenuItem extends React.Component<MenuItemProps> { export class MenuItem extends React.Component<MenuItemProps> {
static contextType = OptionsContext;
ref = React.createRef<HTMLLabelElement>(); ref = React.createRef<HTMLLabelElement>();
activate = (evt: React.MouseEvent<HTMLElement>) => { activate = (evt: React.MouseEvent<HTMLElement>) => {
@ -40,6 +43,7 @@ export class MenuItem extends React.Component<MenuItemProps> {
render() { render() {
const { item, withoutChildren } = this.props; const { item, withoutChildren } = this.props;
const hideShelfIcon = this.context.hideShelfIcon;
return ( return (
<MenuItemLi onClick={this.activate} depth={item.depth} data-item-id={item.id}> <MenuItemLi onClick={this.activate} depth={item.depth} data-item-id={item.id}>
{item.type === 'operation' ? ( {item.type === 'operation' ? (
@ -50,7 +54,7 @@ export class MenuItem extends React.Component<MenuItemProps> {
{item.name} {item.name}
{this.props.children} {this.props.children}
</MenuItemTitle> </MenuItemTitle>
{(item.depth > 0 && item.items.length > 0 && ( {(!hideShelfIcon && item.depth > 0 && item.items.length > 0 && (
<ShelfIcon float={'right'} direction={item.expanded ? 'down' : 'right'} /> <ShelfIcon float={'right'} direction={item.expanded ? 'down' : 'right'} />
)) || )) ||
null} null}
@ -74,6 +78,8 @@ export interface OperationMenuItemContentProps {
@observer @observer
export class OperationMenuItemContent extends React.Component<OperationMenuItemContentProps> { export class OperationMenuItemContent extends React.Component<OperationMenuItemContentProps> {
static contextType = OptionsContext;
ref = React.createRef<HTMLLabelElement>(); ref = React.createRef<HTMLLabelElement>();
componentDidUpdate() { componentDidUpdate() {
@ -84,6 +90,7 @@ export class OperationMenuItemContent extends React.Component<OperationMenuItemC
render() { render() {
const { item } = this.props; const { item } = this.props;
const hideHttpVerbsMenu = this.context.hideHttpVerbs;
return ( return (
<MenuItemLabel <MenuItemLabel
depth={item.depth} depth={item.depth}
@ -94,7 +101,9 @@ export class OperationMenuItemContent extends React.Component<OperationMenuItemC
{item.isWebhook ? ( {item.isWebhook ? (
<OperationBadge type="hook">{l('webhook')}</OperationBadge> <OperationBadge type="hook">{l('webhook')}</OperationBadge>
) : ( ) : (
!hideHttpVerbsMenu && (
<OperationBadge type={item.httpVerb}>{shortenHTTPVerb(item.httpVerb)}</OperationBadge> <OperationBadge type={item.httpVerb}>{shortenHTTPVerb(item.httpVerb)}</OperationBadge>
)
)} )}
<MenuItemTitle width="calc(100% - 38px)"> <MenuItemTitle width="calc(100% - 38px)">
{item.name} {item.name}

View File

@ -1,10 +1,10 @@
import defaultTheme, { ResolvedThemeInterface, resolveTheme, ThemeInterface } from '../theme'; import defaultTheme, { ResolvedThemeInterface, resolveTheme, ThemeInterface } from '../theme';
import { querySelector } from '../utils/dom'; import { querySelector } from '../utils/dom';
import { isNumeric, mergeObjects } from '../utils/helpers'; import { isNumeric, mergeObjects } from '../utils/helpers';
import { LabelsConfigRaw, setRedocLabels } from './Labels'; import { LabelsConfigRaw, setRedocLabels } from './Labels';
import { MDXComponentMeta } from './MarkdownRenderer'; import { MDXComponentMeta } from './MarkdownRenderer';
export interface RedocRawOptions { export interface RedocRawOptions {
theme?: ThemeInterface; theme?: ThemeInterface;
scrollYOffset?: number | string | (() => number); scrollYOffset?: number | string | (() => number);
@ -29,6 +29,9 @@ export interface RedocRawOptions {
simpleOneOfTypeLabel?: boolean | string; simpleOneOfTypeLabel?: boolean | string;
payloadSampleIdx?: number; payloadSampleIdx?: number;
expandSingleSchemaField?: boolean | string; expandSingleSchemaField?: boolean | string;
expandAllSchemaFields?: boolean | string;
hideShelfIcon?: boolean | string;
hideHttpVerbs?: boolean | string;
unstable_ignoreMimeParameters?: boolean; unstable_ignoreMimeParameters?: boolean;
@ -184,6 +187,9 @@ export class RedocNormalizedOptions {
simpleOneOfTypeLabel: boolean; simpleOneOfTypeLabel: boolean;
payloadSampleIdx: number; payloadSampleIdx: number;
expandSingleSchemaField: boolean; expandSingleSchemaField: boolean;
expandAllSchemaFields: boolean;
hideShelfIcon: boolean;
hideHttpVerbs: boolean;
/* tslint:disable-next-line */ /* tslint:disable-next-line */
unstable_ignoreMimeParameters: boolean; unstable_ignoreMimeParameters: boolean;
@ -240,6 +246,9 @@ 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.expandAllSchemaFields = argValueToBoolean(raw.expandAllSchemaFields);
this.hideShelfIcon = argValueToBoolean(raw.hideShelfIcon);
this.hideHttpVerbs = argValueToBoolean(raw.hideHttpVerbs);
this.unstable_ignoreMimeParameters = argValueToBoolean(raw.unstable_ignoreMimeParameters); this.unstable_ignoreMimeParameters = argValueToBoolean(raw.unstable_ignoreMimeParameters);

View File

@ -1,17 +1,17 @@
import { action, observable } from 'mobx'; import { action, observable } from 'mobx';
import { import {
OpenAPIParameter, OpenAPIParameter,
OpenAPIParameterLocation, OpenAPIParameterLocation,
OpenAPIParameterStyle, OpenAPIParameterStyle,
Referenced, Referenced
} from '../../types'; } from '../../types';
import { RedocNormalizedOptions } from '../RedocNormalizedOptions';
import { extractExtensions } from '../../utils/openapi'; import { extractExtensions } from '../../utils/openapi';
import { OpenAPIParser } from '../OpenAPIParser'; import { OpenAPIParser } from '../OpenAPIParser';
import { RedocNormalizedOptions } from '../RedocNormalizedOptions';
import { SchemaModel } from './Schema'; import { SchemaModel } from './Schema';
const DEFAULT_SERIALIZATION: Record< const DEFAULT_SERIALIZATION: Record<
OpenAPIParameterLocation, OpenAPIParameterLocation,
{ explode: boolean; style: OpenAPIParameterStyle } { explode: boolean; style: OpenAPIParameterStyle }
@ -51,6 +51,7 @@ export class FieldModel {
kind: string; kind: string;
extensions?: Record<string, any>; extensions?: Record<string, any>;
explode: boolean; explode: boolean;
expandAll: boolean;
style?: OpenAPIParameterStyle; style?: OpenAPIParameterStyle;
serializationMime?: string; serializationMime?: string;