mirror of
https://github.com/Redocly/redoc.git
synced 2025-08-08 14:14:56 +03:00
support for a specific vendor extension and toggling content panel area by adding additional option to redoc standalone
This commit is contained in:
parent
965778d3b0
commit
1eae317893
|
@ -17,14 +17,14 @@ info:
|
||||||
It was **extended** to illustrate features of [generator-openapi-repo](https://github.com/Rebilly/generator-openapi-repo)
|
It was **extended** to illustrate features of [generator-openapi-repo](https://github.com/Rebilly/generator-openapi-repo)
|
||||||
tool and [ReDoc](https://github.com/Rebilly/ReDoc) documentation. In addition to standard
|
tool and [ReDoc](https://github.com/Rebilly/ReDoc) documentation. In addition to standard
|
||||||
OpenAPI syntax we use a few [vendor extensions](https://github.com/Rebilly/ReDoc/blob/master/docs/redoc-vendor-extensions.md).
|
OpenAPI syntax we use a few [vendor extensions](https://github.com/Rebilly/ReDoc/blob/master/docs/redoc-vendor-extensions.md).
|
||||||
|
|
||||||
# OpenAPI Specification
|
# OpenAPI Specification
|
||||||
This API is documented in **OpenAPI format** and is based on
|
This API is documented in **OpenAPI format** and is based on
|
||||||
[Petstore sample](http://petstore.swagger.io/) provided by [swagger.io](http://swagger.io) team.
|
[Petstore sample](http://petstore.swagger.io/) provided by [swagger.io](http://swagger.io) team.
|
||||||
It was **extended** to illustrate features of [generator-openapi-repo](https://github.com/Rebilly/generator-openapi-repo)
|
It was **extended** to illustrate features of [generator-openapi-repo](https://github.com/Rebilly/generator-openapi-repo)
|
||||||
tool and [ReDoc](https://github.com/Rebilly/ReDoc) documentation. In addition to standard
|
tool and [ReDoc](https://github.com/Rebilly/ReDoc) documentation. In addition to standard
|
||||||
OpenAPI syntax we use a few [vendor extensions](https://github.com/Rebilly/ReDoc/blob/master/docs/redoc-vendor-extensions.md).
|
OpenAPI syntax we use a few [vendor extensions](https://github.com/Rebilly/ReDoc/blob/master/docs/redoc-vendor-extensions.md).
|
||||||
|
|
||||||
# Cross-Origin Resource Sharing
|
# Cross-Origin Resource Sharing
|
||||||
This API features Cross-Origin Resource Sharing (CORS) implemented in compliance with [W3C spec](https://www.w3.org/TR/cors/).
|
This API features Cross-Origin Resource Sharing (CORS) implemented in compliance with [W3C spec](https://www.w3.org/TR/cors/).
|
||||||
And that allows cross-domain communication from the browser.
|
And that allows cross-domain communication from the browser.
|
||||||
|
@ -38,8 +38,9 @@ info:
|
||||||
OAuth2 - an open protocol to allow secure authorization in a simple
|
OAuth2 - an open protocol to allow secure authorization in a simple
|
||||||
and standard method from web, mobile and desktop applications.
|
and standard method from web, mobile and desktop applications.
|
||||||
|
|
||||||
<security-definitions />
|
<security-definitions />
|
||||||
|
|
||||||
|
x-opentext-other: foo
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
title: Swagger Petstore
|
title: Swagger Petstore
|
||||||
termsOfService: 'http://swagger.io/terms/'
|
termsOfService: 'http://swagger.io/terms/'
|
||||||
|
@ -82,6 +83,7 @@ paths:
|
||||||
type: integer
|
type: integer
|
||||||
format: int64
|
format: int64
|
||||||
post:
|
post:
|
||||||
|
x-opentext-other: bar
|
||||||
tags:
|
tags:
|
||||||
- pet
|
- pet
|
||||||
summary: Add a new pet to the store
|
summary: Add a new pet to the store
|
||||||
|
|
|
@ -1,20 +1,16 @@
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { StyledLink } from '../../../src/common-elements';
|
import { Constants } from '../../../src/services/Constants';
|
||||||
|
import { DarkRightPanel, StyledLink } from '../../../src/common-elements';
|
||||||
import { AppStore } from '../../services/AppStore';
|
import { ContentPanel } from '../RightPanelContent/ContentPanel';
|
||||||
|
|
||||||
import { MiddlePanel, Row, Section } from '../../common-elements/';
|
import { MiddlePanel, Row, Section } from '../../common-elements/';
|
||||||
|
|
||||||
|
import { AppStore } from '../../services/AppStore';
|
||||||
import { ExternalDocumentation } from '../ExternalDocumentation/ExternalDocumentation';
|
import { ExternalDocumentation } from '../ExternalDocumentation/ExternalDocumentation';
|
||||||
import { Markdown } from '../Markdown/Markdown';
|
import { Markdown } from '../Markdown/Markdown';
|
||||||
import { StyledMarkdownBlock } from '../Markdown/styled.elements';
|
import { StyledMarkdownBlock } from '../Markdown/styled.elements';
|
||||||
import {
|
import { ApiHeader, DownloadButton, InfoSpan, InfoSpanBox, InfoSpanBoxWrap, } from './styled.elements';
|
||||||
ApiHeader,
|
|
||||||
DownloadButton,
|
|
||||||
InfoSpan,
|
|
||||||
InfoSpanBox,
|
|
||||||
InfoSpanBoxWrap,
|
|
||||||
} from './styled.elements';
|
|
||||||
|
|
||||||
export interface ApiInfoProps {
|
export interface ApiInfoProps {
|
||||||
store: AppStore;
|
store: AppStore;
|
||||||
|
@ -29,8 +25,8 @@ export class ApiInfo extends React.Component<ApiInfoProps> {
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { store } = this.props;
|
const {store} = this.props;
|
||||||
const { info, externalDocs } = store.spec;
|
const {info, externalDocs} = store.spec;
|
||||||
const hideDownloadButton = store.options.hideDownloadButton;
|
const hideDownloadButton = store.options.hideDownloadButton;
|
||||||
|
|
||||||
const downloadFilename = info.downloadFileName;
|
const downloadFilename = info.downloadFileName;
|
||||||
|
@ -105,11 +101,13 @@ export class ApiInfo extends React.Component<ApiInfoProps> {
|
||||||
</InfoSpanBox>
|
</InfoSpanBox>
|
||||||
</InfoSpanBoxWrap>
|
</InfoSpanBoxWrap>
|
||||||
)) ||
|
)) ||
|
||||||
null}
|
null}
|
||||||
</StyledMarkdownBlock>
|
</StyledMarkdownBlock>
|
||||||
<Markdown source={store.spec.info.description} />
|
<Markdown source={store.spec.info.description}/>
|
||||||
{externalDocs && <ExternalDocumentation externalDocs={externalDocs} />}
|
{externalDocs && <ExternalDocumentation externalDocs={externalDocs}/>}
|
||||||
</MiddlePanel>
|
</MiddlePanel>
|
||||||
|
{store.options.showOtherInfoPanel &&
|
||||||
|
<DarkRightPanel><ContentPanel content={info[Constants.OTX_EXTENSION_KEY]}/></DarkRightPanel>}
|
||||||
</Row>
|
</Row>
|
||||||
</Section>
|
</Section>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,24 +1,22 @@
|
||||||
import * as React from 'react';
|
|
||||||
import { SecurityRequirements } from '../SecurityRequirement/SecurityRequirement';
|
|
||||||
|
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
|
import * as React from 'react';
|
||||||
|
import { OperationPanel } from '../RightPanelContent/OperationPanel';
|
||||||
|
|
||||||
import { Badge, DarkRightPanel, H2, MiddlePanel, Row } from '../../common-elements';
|
import { Badge, DarkRightPanel, H2, MiddlePanel, Row } from '../../common-elements';
|
||||||
|
|
||||||
import { OptionsContext } from '../OptionsProvider';
|
|
||||||
|
|
||||||
import { ShareLink } from '../../common-elements/linkify';
|
import { ShareLink } from '../../common-elements/linkify';
|
||||||
import { Endpoint } from '../Endpoint/Endpoint';
|
|
||||||
import { ExternalDocumentation } from '../ExternalDocumentation/ExternalDocumentation';
|
|
||||||
import { Markdown } from '../Markdown/Markdown';
|
|
||||||
import { Parameters } from '../Parameters/Parameters';
|
|
||||||
import { RequestSamples } from '../RequestSamples/RequestSamples';
|
|
||||||
import { ResponsesList } from '../Responses/ResponsesList';
|
|
||||||
import { ResponseSamples } from '../ResponseSamples/ResponseSamples';
|
|
||||||
|
|
||||||
import { OperationModel as OperationType } from '../../services/models';
|
import { OperationModel as OperationType } from '../../services/models';
|
||||||
import styled from '../../styled-components';
|
import styled from '../../styled-components';
|
||||||
|
import { Endpoint } from '../Endpoint/Endpoint';
|
||||||
|
import { ExternalDocumentation } from '../ExternalDocumentation/ExternalDocumentation';
|
||||||
import { Extensions } from '../Fields/Extensions';
|
import { Extensions } from '../Fields/Extensions';
|
||||||
|
import { Markdown } from '../Markdown/Markdown';
|
||||||
|
|
||||||
|
import { OptionsContext } from '../OptionsProvider';
|
||||||
|
import { Parameters } from '../Parameters/Parameters';
|
||||||
|
import { ResponsesList } from '../Responses/ResponsesList';
|
||||||
|
import { SecurityRequirements } from '../SecurityRequirement/SecurityRequirement';
|
||||||
|
|
||||||
const OperationRow = styled(Row)`
|
const OperationRow = styled(Row)`
|
||||||
backface-visibility: hidden;
|
backface-visibility: hidden;
|
||||||
|
@ -28,7 +26,7 @@ const OperationRow = styled(Row)`
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const Description = styled.div`
|
const Description = styled.div`
|
||||||
margin-bottom: ${({ theme }) => theme.spacing.unit * 6}px;
|
margin-bottom: ${({theme}) => theme.spacing.unit * 6}px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export interface OperationProps {
|
export interface OperationProps {
|
||||||
|
@ -38,9 +36,9 @@ export interface OperationProps {
|
||||||
@observer
|
@observer
|
||||||
export class Operation extends React.Component<OperationProps> {
|
export class Operation extends React.Component<OperationProps> {
|
||||||
render() {
|
render() {
|
||||||
const { operation } = this.props;
|
const {operation} = this.props;
|
||||||
|
|
||||||
const { name: summary, description, deprecated, externalDocs } = operation;
|
const {name: summary, description, deprecated, externalDocs} = operation;
|
||||||
const hasDescription = !!(description || externalDocs);
|
const hasDescription = !!(description || externalDocs);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -49,25 +47,23 @@ export class Operation extends React.Component<OperationProps> {
|
||||||
<OperationRow>
|
<OperationRow>
|
||||||
<MiddlePanel>
|
<MiddlePanel>
|
||||||
<H2>
|
<H2>
|
||||||
<ShareLink to={operation.id} />
|
<ShareLink to={operation.id}/>
|
||||||
{summary} {deprecated && <Badge type="warning"> Deprecated </Badge>}
|
{summary} {deprecated && <Badge type="warning"> Deprecated </Badge>}
|
||||||
</H2>
|
</H2>
|
||||||
{options.pathInMiddlePanel && <Endpoint operation={operation} inverted={true} />}
|
{options.pathInMiddlePanel && <Endpoint operation={operation} inverted={true}/>}
|
||||||
{hasDescription && (
|
{hasDescription && (
|
||||||
<Description>
|
<Description>
|
||||||
{description !== undefined && <Markdown source={description} />}
|
{description !== undefined && <Markdown source={description}/>}
|
||||||
{externalDocs && <ExternalDocumentation externalDocs={externalDocs} />}
|
{externalDocs && <ExternalDocumentation externalDocs={externalDocs}/>}
|
||||||
</Description>
|
</Description>
|
||||||
)}
|
)}
|
||||||
<Extensions extensions={operation.extensions} />
|
<Extensions extensions={operation.extensions}/>
|
||||||
<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}/>
|
||||||
</MiddlePanel>
|
</MiddlePanel>
|
||||||
<DarkRightPanel>
|
<DarkRightPanel>
|
||||||
{!options.pathInMiddlePanel && <Endpoint operation={operation} />}
|
<OperationPanel operation={operation} options={options}/>
|
||||||
<RequestSamples operation={operation} />
|
|
||||||
<ResponseSamples operation={operation} />
|
|
||||||
</DarkRightPanel>
|
</DarkRightPanel>
|
||||||
</OperationRow>
|
</OperationRow>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
import * as PropTypes from 'prop-types';
|
import * as PropTypes from 'prop-types';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
import { ContentItems } from '../../../src/components';
|
||||||
import { ThemeProvider } from '../../styled-components';
|
|
||||||
import { OptionsProvider } from '../OptionsProvider';
|
|
||||||
|
|
||||||
import { AppStore } from '../../services';
|
import { AppStore } from '../../services';
|
||||||
|
|
||||||
|
import { ThemeProvider } from '../../styled-components';
|
||||||
import { ApiInfo } from '../ApiInfo/';
|
import { ApiInfo } from '../ApiInfo/';
|
||||||
import { ApiLogo } from '../ApiLogo/ApiLogo';
|
import { ApiLogo } from '../ApiLogo/ApiLogo';
|
||||||
import { ContentItems } from '../ContentItems/ContentItems';
|
import { OptionsProvider } from '../OptionsProvider';
|
||||||
import { SideMenu } from '../SideMenu/SideMenu';
|
|
||||||
import { StickyResponsiveSidebar } from '../StickySidebar/StickyResponsiveSidebar';
|
|
||||||
import { ApiContentWrap, BackgroundStub, RedocWrap } from './styled.elements';
|
|
||||||
|
|
||||||
import { SearchBox } from '../SearchBox/SearchBox';
|
import { SearchBox } from '../SearchBox/SearchBox';
|
||||||
|
import { SideMenu } from '../SideMenu/SideMenu';
|
||||||
|
import { StickyResponsiveSidebar } from '../StickySidebar/StickyResponsiveSidebar';
|
||||||
import { StoreProvider } from '../StoreBuilder';
|
import { StoreProvider } from '../StoreBuilder';
|
||||||
|
import { ApiContentWrap, BackgroundStub, RedocWrap } from './styled.elements';
|
||||||
|
|
||||||
export interface RedocProps {
|
export interface RedocProps {
|
||||||
store: AppStore;
|
store: AppStore;
|
||||||
|
|
24
src/components/RightPanelContent/ContentPanel.tsx
Normal file
24
src/components/RightPanelContent/ContentPanel.tsx
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
import { observer } from 'mobx-react';
|
||||||
|
import * as React from 'react';
|
||||||
|
import { MiddlePanel, Row } from '../../../src/common-elements';
|
||||||
|
|
||||||
|
interface ContentPanelProps {
|
||||||
|
content: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@observer
|
||||||
|
export class ContentPanel extends React.Component<ContentPanelProps> {
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Row>
|
||||||
|
<MiddlePanel>
|
||||||
|
<h1>
|
||||||
|
{this.props.content}
|
||||||
|
</h1>
|
||||||
|
</MiddlePanel>
|
||||||
|
</Row>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
37
src/components/RightPanelContent/OperationPanel.tsx
Normal file
37
src/components/RightPanelContent/OperationPanel.tsx
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
import { observer } from 'mobx-react';
|
||||||
|
import * as React from 'react';
|
||||||
|
import { ResponseSamples } from '../../../src/components';
|
||||||
|
import { Endpoint } from '../../../src/components/Endpoint/Endpoint';
|
||||||
|
import { RequestSamples } from '../../../src/components/RequestSamples/RequestSamples';
|
||||||
|
import { RedocNormalizedOptions } from '../../../src/services';
|
||||||
|
import { Constants } from '../../../src/services/Constants';
|
||||||
|
import { OperationModel } from '../../../src/services/models';
|
||||||
|
import { ContentPanel } from './/ContentPanel';
|
||||||
|
|
||||||
|
interface RightPanelContentProps {
|
||||||
|
operation: OperationModel;
|
||||||
|
options: RedocNormalizedOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
@observer
|
||||||
|
export class OperationPanel extends React.Component<RightPanelContentProps> {
|
||||||
|
render() {
|
||||||
|
if (this.shouldShowOtherInfoPanel()) {
|
||||||
|
return <ContentPanel content={this.props.operation.extensions[Constants.OTX_EXTENSION_KEY]}/>;
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{!this.props.options.pathInMiddlePanel && <Endpoint operation={this.props.operation}/>}
|
||||||
|
<RequestSamples operation={this.props.operation}/>
|
||||||
|
<ResponseSamples operation={this.props.operation}/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private shouldShowOtherInfoPanel() {
|
||||||
|
return this.props.options.showOtherInfoPanel &&
|
||||||
|
this.props.options.showExtensions &&
|
||||||
|
this.props.operation.extensions[Constants.OTX_EXTENSION_KEY];
|
||||||
|
}
|
||||||
|
}
|
3
src/services/Constants.ts
Normal file
3
src/services/Constants.ts
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
export class Constants {
|
||||||
|
static readonly OTX_EXTENSION_KEY = 'x-opentext-other';
|
||||||
|
}
|
|
@ -20,6 +20,7 @@ export interface RedocRawOptions {
|
||||||
disableSearch?: boolean | string;
|
disableSearch?: boolean | string;
|
||||||
onlyRequiredInSamples?: boolean | string;
|
onlyRequiredInSamples?: boolean | string;
|
||||||
showExtensions?: boolean | string | string[];
|
showExtensions?: boolean | string | string[];
|
||||||
|
showOtherInfoPanel?: boolean;
|
||||||
|
|
||||||
unstable_ignoreMimeParameters?: boolean;
|
unstable_ignoreMimeParameters?: boolean;
|
||||||
|
|
||||||
|
@ -120,6 +121,7 @@ export class RedocNormalizedOptions {
|
||||||
disableSearch: boolean;
|
disableSearch: boolean;
|
||||||
onlyRequiredInSamples: boolean;
|
onlyRequiredInSamples: boolean;
|
||||||
showExtensions: boolean | string[];
|
showExtensions: boolean | string[];
|
||||||
|
showOtherInfoPanel: boolean;
|
||||||
|
|
||||||
/* tslint:disable-next-line */
|
/* tslint:disable-next-line */
|
||||||
unstable_ignoreMimeParameters: boolean;
|
unstable_ignoreMimeParameters: boolean;
|
||||||
|
@ -147,6 +149,7 @@ export class RedocNormalizedOptions {
|
||||||
this.disableSearch = argValueToBoolean(raw.disableSearch);
|
this.disableSearch = argValueToBoolean(raw.disableSearch);
|
||||||
this.onlyRequiredInSamples = argValueToBoolean(raw.onlyRequiredInSamples);
|
this.onlyRequiredInSamples = argValueToBoolean(raw.onlyRequiredInSamples);
|
||||||
this.showExtensions = RedocNormalizedOptions.normalizeShowExtensions(raw.showExtensions);
|
this.showExtensions = RedocNormalizedOptions.normalizeShowExtensions(raw.showExtensions);
|
||||||
|
this.showOtherInfoPanel = argValueToBoolean(raw.showOtherInfoPanel);
|
||||||
|
|
||||||
this.unstable_ignoreMimeParameters = argValueToBoolean(raw.unstable_ignoreMimeParameters);
|
this.unstable_ignoreMimeParameters = argValueToBoolean(raw.unstable_ignoreMimeParameters);
|
||||||
|
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
interface ServerStub {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class produces canned responses for a given OpenAPI spec
|
|
||||||
*/
|
|
||||||
export class OpenApiServerStub implements ServerStub {
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,6 +0,0 @@
|
||||||
describe('ServerStub', () => {
|
|
||||||
test('TODO IMPLEMENT ME', () => {
|
|
||||||
const fn = jest.fn();
|
|
||||||
expect(fn).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
Loading…
Reference in New Issue
Block a user