External Documentation rendered for groups, operations and schemata.

URL for External Documentation is required.
This commit is contained in:
Matthias Mohr 2018-08-06 17:20:24 +02:00
parent 568ce74077
commit e5ed542fed
9 changed files with 60 additions and 11 deletions

View File

@ -5,6 +5,7 @@ import { AppStore } from '../../services/AppStore';
import { MiddlePanel, Row } from '../../common-elements/'; import { MiddlePanel, Row } from '../../common-elements/';
import { ExternalDocumentation } from '../ExternalDocumentation/ExternalDocumentation';
import { StyledMarkdownBlock } from '../Markdown/styled.elements'; import { StyledMarkdownBlock } from '../Markdown/styled.elements';
import { import {
ApiHeader, ApiHeader,
@ -97,14 +98,12 @@ export class ApiInfo extends React.Component<ApiInfoProps> {
</InfoSpanBoxWrap> </InfoSpanBoxWrap>
)) || )) ||
null} null}
{(externalDocs && (
<p>
<a href={externalDocs.url}>{externalDocs.description || externalDocs.url}</a>
</p>
)) ||
null}
</StyledMarkdownBlock> </StyledMarkdownBlock>
{externalDocs && (
<p>
<ExternalDocumentation externalDocs={externalDocs} />
</p>
)}
</MiddlePanel> </MiddlePanel>
</Row> </Row>
); );

View File

@ -2,6 +2,7 @@ import { observer } from 'mobx-react';
import * as React from 'react'; import * as React from 'react';
import { SECTION_ATTR } from '../../services/MenuStore'; import { SECTION_ATTR } from '../../services/MenuStore';
import { ExternalDocumentation } from '../ExternalDocumentation/ExternalDocumentation';
import { Markdown } from '../Markdown/Markdown'; import { Markdown } from '../Markdown/Markdown';
import { H1, MiddlePanel, Row, ShareLink } from '../../common-elements'; import { H1, MiddlePanel, Row, ShareLink } from '../../common-elements';
@ -79,7 +80,7 @@ export class ContentItem extends React.Component<ContentItemProps> {
@observer @observer
export class SectionItem extends React.Component<ContentItemProps> { export class SectionItem extends React.Component<ContentItemProps> {
render() { render() {
const { name, description } = this.props.item; const { name, description, externalDocs } = this.props.item;
const components = this.props.allowedMdComponents; const components = this.props.allowedMdComponents;
return ( return (
<Row> <Row>
@ -97,6 +98,11 @@ export class SectionItem extends React.Component<ContentItemProps> {
)} )}
</StoreConsumer> </StoreConsumer>
)} )}
{externalDocs && (
<p>
<ExternalDocumentation externalDocs={externalDocs} />
</p>
)}
</MiddlePanel> </MiddlePanel>
</Row> </Row>
); );

View File

@ -0,0 +1,27 @@
import { observer } from 'mobx-react';
import * as React from 'react';
import styled from '../../styled-components';
import { OpenAPIExternalDocumentation } from '../../types';
import { linksCss } from '../Markdown/styled.elements';
const Link = styled.span`
${linksCss};
`;
@observer
export class ExternalDocumentation extends React.Component<{
externalDocs: OpenAPIExternalDocumentation;
}> {
render() {
const { externalDocs } = this.props;
if (!externalDocs || !externalDocs.url) {
return null;
}
return (
<Link>
<a href={externalDocs.url}>{externalDocs.description || externalDocs.url}</a>
</Link>
);
}
}

View File

@ -9,6 +9,7 @@ import {
TypePrefix, TypePrefix,
TypeTitle, TypeTitle,
} from '../../common-elements/fields'; } from '../../common-elements/fields';
import { ExternalDocumentation } from '../ExternalDocumentation/ExternalDocumentation';
import { Markdown } from '../Markdown/Markdown'; import { Markdown } from '../Markdown/Markdown';
import { EnumValues } from './EnumValues'; import { EnumValues } from './EnumValues';
import { FieldProps } from './Field'; import { FieldProps } from './Field';
@ -46,6 +47,11 @@ export class FieldDetails extends React.PureComponent<FieldProps> {
<div> <div>
<Markdown dense={true} source={description} /> <Markdown dense={true} source={description} />
</div> </div>
{schema.externalDocs && (
<div>
<ExternalDocumentation externalDocs={schema.externalDocs} />
</div>
)}
{(renderDiscriminatorSwitch && renderDiscriminatorSwitch(this.props)) || null} {(renderDiscriminatorSwitch && renderDiscriminatorSwitch(this.props)) || null}
</div> </div>
); );

View File

@ -9,6 +9,7 @@ import { OptionsContext } from '../OptionsProvider';
import { ShareLink } from '../../common-elements/linkify'; import { ShareLink } from '../../common-elements/linkify';
import { Endpoint } from '../Endpoint/Endpoint'; import { Endpoint } from '../Endpoint/Endpoint';
import { ExternalDocumentation } from '../ExternalDocumentation/ExternalDocumentation';
import { Markdown } from '../Markdown/Markdown'; import { Markdown } from '../Markdown/Markdown';
import { Parameters } from '../Parameters/Parameters'; import { Parameters } from '../Parameters/Parameters';
import { RequestSamples } from '../RequestSamples/RequestSamples'; import { RequestSamples } from '../RequestSamples/RequestSamples';
@ -43,7 +44,7 @@ export class Operation extends React.Component<OperationProps> {
render() { render() {
const { operation } = this.props; const { operation } = this.props;
const { name: summary, description, deprecated } = operation; const { name: summary, description, deprecated, externalDocs } = operation;
return ( return (
<OptionsContext.Consumer> <OptionsContext.Consumer>
{options => ( {options => (
@ -55,6 +56,11 @@ export class Operation extends React.Component<OperationProps> {
</H2> </H2>
{options.pathInMiddlePanel && <Endpoint operation={operation} inverted={true} />} {options.pathInMiddlePanel && <Endpoint operation={operation} inverted={true} />}
{description !== undefined && <Markdown source={description} />} {description !== undefined && <Markdown source={description} />}
{externalDocs && (
<p>
<ExternalDocumentation externalDocs={externalDocs} />
</p>
)}
<SecurityRequirements securities={operation.security} /> <SecurityRequirements securities={operation.security} />
<Parameters parameters={operation.parameters} body={operation.requestBody} /> <Parameters parameters={operation.parameters} body={operation.requestBody} />
<ResponsesList responses={operation.responses} /> <ResponsesList responses={operation.responses} />

View File

@ -75,6 +75,7 @@ export class Schema extends React.Component<Partial<SchemaProps>> {
name: '', name: '',
required: false, required: false,
description: schema.description, description: schema.description,
externalDocs: schema.externalDocs,
deprecated: false, deprecated: false,
toggle: () => null, toggle: () => null,
expanded: false, expanded: false,

View File

@ -24,6 +24,7 @@ exports[`Components SchemaView discriminator should correctly render discriminat
"displayType": "number", "displayType": "number",
"enum": Array [], "enum": Array [],
"example": undefined, "example": undefined,
"externalDocs": undefined,
"format": undefined, "format": undefined,
"isCircular": undefined, "isCircular": undefined,
"isPrimitive": true, "isPrimitive": true,
@ -72,6 +73,7 @@ exports[`Components SchemaView discriminator should correctly render discriminat
"displayType": "string", "displayType": "string",
"enum": Array [], "enum": Array [],
"example": undefined, "example": undefined,
"externalDocs": undefined,
"format": undefined, "format": undefined,
"isCircular": undefined, "isCircular": undefined,
"isPrimitive": true, "isPrimitive": true,

View File

@ -1,6 +1,6 @@
import { action, observable } from 'mobx'; import { action, observable } from 'mobx';
import { OpenAPISchema, Referenced } from '../../types'; import { OpenAPIExternalDocumentation, OpenAPISchema, Referenced } from '../../types';
import { OpenAPIParser } from '../OpenAPIParser'; import { OpenAPIParser } from '../OpenAPIParser';
import { RedocNormalizedOptions } from '../RedocNormalizedOptions'; import { RedocNormalizedOptions } from '../RedocNormalizedOptions';
@ -25,6 +25,7 @@ export class SchemaModel {
typePrefix: string = ''; typePrefix: string = '';
title: string; title: string;
description: string; description: string;
externalDocs?: OpenAPIExternalDocumentation;
isPrimitive: boolean; isPrimitive: boolean;
isCircular: boolean = false; isCircular: boolean = false;
@ -100,6 +101,7 @@ export class SchemaModel {
this.example = schema.example; this.example = schema.example;
this.deprecated = !!schema.deprecated; this.deprecated = !!schema.deprecated;
this.pattern = schema.pattern; this.pattern = schema.pattern;
this.externalDocs = schema.externalDocs;
this.constraints = humanizeConstraints(schema); this.constraints = humanizeConstraints(schema);
this.displayType = this.type; this.displayType = this.type;

View File

@ -255,7 +255,7 @@ export interface OpenAPITag {
export interface OpenAPIExternalDocumentation { export interface OpenAPIExternalDocumentation {
description?: string; description?: string;
url?: string; url: string;
} }
export interface OpenAPIContact { export interface OpenAPIContact {