Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support externalDocs. Closes #112 #177

Merged
merged 6 commits into from
Jul 16, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p

## [Unreleased]

- Lincoln can now display `additionalProperties`
### Added

- [#91](https://github.com/temando/open-api-renderer/issues/91) Lincoln learnt how to display `additionalProperties`.
- [#157](https://github.com/temando/open-api-renderer/issues/157) Lincoln learnt how to display `servers` and path information.
- [#112](https://github.com/temando/open-api-renderer/issues/112) Lincoln learnt how to display `externalDocs`.

## [v0.0.6] - 2017-07-07

Expand Down
1 change: 0 additions & 1 deletion docs/demo/demo.81f8cdaf8e92e7c02fcc.js

This file was deleted.

1 change: 1 addition & 0 deletions docs/demo/demo.d73ff4397f0035ac6394.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/demo/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body><script type="text/javascript" src="manifest.64e52d4be3e1405eba34.js"></script><script type="text/javascript" src="vendor.cda98230d6573ec02868.js"></script><script type="text/javascript" src="demo.81f8cdaf8e92e7c02fcc.js"></script></body>
<body><script type="text/javascript" src="manifest.81c1f8c28d950ee22175.js"></script><script type="text/javascript" src="vendor.5e42313e188f293e0550.js"></script><script type="text/javascript" src="demo.d73ff4397f0035ac6394.js"></script></body>
</html>

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions docs/open-api-v3-support.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ This document outlines this project's support for visualising the [Open API V3][
- [ ] [components](#components-object)
- [x] [security](#security-requirement-object)
- [x] [tags](#tag-object)
- [ ] [externalDocs](#external-documentation-object)
- [x] [externalDocs](#external-documentation-object)

### [Info](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.md#info-object) object

Expand Down Expand Up @@ -104,7 +104,7 @@ This is supported by default as all `$ref` are dereferenced before the definitio
- [x] tags
- [x] summary
- [x] description
- [ ] [externalDocs](#external-documentation-object)
- [x] [externalDocs](#external-documentation-object)
- [ ] operationId
- [x] [parameters](#parameter-object)
- [x] [requestBody](#request-body-object)
Expand All @@ -116,8 +116,8 @@ This is supported by default as all `$ref` are dereferenced before the definitio

### [External Documentation](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.md#external-documentation-object) object

- [ ] description
- [ ] url
- [x] description
- [x] url

### [Parameter](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.md#parameter-object) object

Expand Down Expand Up @@ -209,7 +209,7 @@ See [parameter](#parameter-object) object.

- [x] name
- [x] description
- [ ] [externalDocs](#external-documentation-object)
- [x] [externalDocs](#external-documentation-object)

### [Reference](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.md#reference-object) object

Expand Down Expand Up @@ -263,7 +263,7 @@ The OpenAPI specification also supports several additional properties from JSON
- [ ] readOnly
- [ ] writeOnly
- [ ] [xml](#xml-object)
- [ ] [externalDocs](#external-documentation-object)
- [x] [externalDocs](#external-documentation-object)
- [ ] example
- [ ] deprecated

Expand Down
12 changes: 3 additions & 9 deletions src/components/BodyContent/BodyContent.styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ export const styles = createSheet(({ text, backgrounds, sizes }) => ({
'bodyContent': {
display: 'table',
width: '100%',
padding: '10px',
padding: '1rem 0',
boxSizing: 'border-box'
},

'tabs': {
'& > div': {
display: 'inline-block',
padding: '10px 20px',
padding: '1rem 2rem',
cursor: 'pointer',

'&:not($active)': {
Expand All @@ -23,12 +23,6 @@ export const styles = createSheet(({ text, backgrounds, sizes }) => ({

'active': {
backgroundColor: `${backgrounds.schema}`,
borderRadius: '10px 10px 0 0'
},

[`@media (max-width: ${sizes.breakpoint})`]: {
'bodyContent': {
padding: '10px 0'
}
borderRadius: '1rem 1rem 0 0'
}
}))
1 change: 1 addition & 0 deletions src/components/BodySchema/BodySchema.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ export default class BodySchema extends Component {
defaultValue={property.defaultValue}
constraints={property.constraints}
attributes={property.attributes}
docs={property.docs}
onClick={hasSubset ? this.onClick : undefined}
isRequired={property.required}
isOpen={isOpen}
Expand Down
10 changes: 2 additions & 8 deletions src/components/ContentContainer/ContentContainer.styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,13 @@ import { createSheet } from '../../theme'

export const styles = createSheet(({ sizes }) => ({
'contentContainer': {
padding: '20px 0',

'& h2': {
paddingLeft: '2rem'
}
padding: '0.5rem 2rem',
margin: '1rem 0'
},

[`@media (max-width: ${sizes.breakpoint})`]: {
'contentContainer': {
padding: '10px 0',

'& h2': {
paddingLeft: '1rem',
margin: 0
}
}
Expand Down
10 changes: 5 additions & 5 deletions src/components/Description/Description.styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@ import { createSheet } from '../../theme'

export const styles = createSheet(({ text }) => ({
'description': {
'&:not($inline)': {
color: `${c(text.default).lighten(0.3)}`,
fontSize: '0.9em'
},
color: `${c(text.default).lighten(0.3)}`,
fontSize: '1rem',

'&$inline': {
'&, & p': {
Expand All @@ -17,5 +15,7 @@ export const styles = createSheet(({ text }) => ({
margin: '.5rem 0'
}
},
'inline': {}
'inline': {
paddingRight: '.2rem'
}
}))
27 changes: 27 additions & 0 deletions src/components/Docs/Docs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React, { PureComponent } from 'react'
import PropTypes from 'prop-types'
import classNames from 'classnames'

import Description from '../Description/Description'
import ExternalLink from '../ExternalLink/ExternalLink'
import { styles } from './Docs.styles'

@styles
export default class Docs extends PureComponent {
render () {
const { url, description, classes } = this.props

return (
<div className={classNames(classes.docs)}>
{description && <Description description={description} />}
<ExternalLink href={url}>More information »</ExternalLink>
</div>
)
}
}

Docs.propTypes = {
description: PropTypes.string,
url: PropTypes.string.isRequired,
classes: PropTypes.object
}
7 changes: 7 additions & 0 deletions src/components/Docs/Docs.styles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { createSheet } from '../../theme'

export const styles = createSheet(() => ({
'docs': {
margin: '0.5rem 0'
}
}))
9 changes: 8 additions & 1 deletion src/components/Header/Header.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { PureComponent } from 'react'
import PropTypes from 'prop-types'

import Docs from '../Docs/Docs'
import Description from '../Description/Description'
import ExternalLink from '../ExternalLink/ExternalLink'
import { styles } from './Header.styles'
Expand Down Expand Up @@ -28,6 +29,8 @@ export default class Header extends PureComponent {
{info && info.termsOfService &&
<ExternalLink href={info.termsOfService}>Terms of Service</ExternalLink>}
</nav>

{info && info.docs && <Docs {...info.docs} />}
</header>
)
}
Expand Down Expand Up @@ -88,7 +91,11 @@ Header.propTypes = {
info: PropTypes.shape({
contact: PropTypes.object,
license: PropTypes.object,
termsOfService: PropTypes.string
termsOfService: PropTypes.string,
docs: PropTypes.shape({
description: PropTypes.string,
url: PropTypes.string.isRequired
})
}),
definitionUrl: PropTypes.string,
classes: PropTypes.object
Expand Down
2 changes: 1 addition & 1 deletion src/components/Header/Header.styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { createSheet } from '../../theme'

export const styles = createSheet(({ borders, sizes }) => ({
'header': {
padding: '0 20px',
padding: '0 2rem',

'& h1': {
marginBottom: '.5rem'
Expand Down
2 changes: 1 addition & 1 deletion src/components/Method/Method.styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export const styles = createSheet(({ borders, text, sizes }) => ({
method: {
borderBottom: `1px solid ${borders.default}`,
margin: '0 1rem 2rem 0',
padding: '1rem 2rem',
padding: '1rem 0',

'& > h3': {
display: 'inline-block',
Expand Down
29 changes: 26 additions & 3 deletions src/components/Page/Page.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,17 @@ export default class Page extends Component {
/>
{security && this.renderSecurity(security)}
<ContentContainer>
{services && services.map(
(service) => <ServiceContainer key={service.title} service={service} initialSchemaTreeDepth={initialSchemaTreeDepth} />
)}
{services && services.map((service) => {
const serviceWithDocs = Object.assign({}, service, this.findTagDocs(service.title, navigation))

return (
<ServiceContainer
key={service.title}
service={serviceWithDocs}
initialSchemaTreeDepth={initialSchemaTreeDepth}
/>
)
})}
</ContentContainer>
</div>
</div>
Expand All @@ -68,6 +76,21 @@ export default class Page extends Component {
)
}

findTagDocs (tagHandle, navigation) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With this approach, the UI component is getting 'smart', as it is now understanding the relationship between services and navigation.

Another approach is to keep the UI component really simple, and handle externalDocs at the parser level.

What do you reckon @brendo ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed, bit tricky, the parser is then making assumptions that the UI can't display tag information together (which we currently can't, as the tags form the navigation).

Secondly the parser is a bit hairy to make this possible right now :(

// Find navigation tag that matches given `tagHandle`, and if has docs.
// Note: tag.methods is a way to determine if the navigation has tags at all.
const navigationTag = navigation.find((tag) => (tag.methods && tag.handle === tagHandle && tag.docs))

// No tag, no additional docs.
if (!navigationTag) {
return {}
}

return {
docs: navigationTag.docs
}
}

onToggleNavigation () {
const { isNavOpen } = this.state
if (isNavOpen) {
Expand Down
14 changes: 10 additions & 4 deletions src/components/Property/Property.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import React, { PureComponent } from 'react'
import classNames from 'classnames'
import PropTypes from 'prop-types'

import Docs from '../Docs/Docs'
import Description from '../Description/Description'
import Indicator from '../Indicator/Indicator'
import PropertyConstraints from './PropertyConstraints/PropertyConstraints'
Expand Down Expand Up @@ -47,9 +49,8 @@ export default class Property extends PureComponent {

render () {
const {
type, title, description, constraints, isRequired,
defaultValue, onClick, isOpen, isLast, attributes,
classes
type, title, description, constraints, docs, defaultValue, attributes,
isRequired, isOpen, isLast, onClick, classes
} = this.props

const {name, isEnumTrimmed} = this.state
Expand Down Expand Up @@ -99,11 +100,12 @@ export default class Property extends PureComponent {
<span className={classes.format}>&lt;{constraints.format}&gt;</span>}
</span>
<PropertyConstraints constraints={constraints} type={type} isRequired={isRequired} />
{((enumValues && enumValues.length) || defaultValue || description) &&
{((enumValues && enumValues.length) || defaultValue || description || docs) &&
<div className={classes.additionalInfo}>
{enumValues && this.renderEnumValues(enumValues, isEnumTrimmed)}
{defaultValue !== undefined && this.renderDefaultValue(defaultValue)}
{description && <div><Description isInline description={description} /></div>}
{docs && <Docs {...docs} />}
</div>
}
</td>
Expand Down Expand Up @@ -184,6 +186,10 @@ Property.propTypes = {
pattern: PropTypes.string,
uniqueItems: PropTypes.bool
}),
docs: PropTypes.shape({
description: PropTypes.string,
url: PropTypes.string.isRequired
}),
enumValues: PropTypes.array,
defaultValue: PropTypes.any,
isRequired: PropTypes.bool,
Expand Down
8 changes: 1 addition & 7 deletions src/components/SecurityContainer/SecurityContainer.styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { createSheet } from '../../theme'

export const styles = createSheet(({ backgrounds, borders, sizes }) => ({
'securityContainer': {
padding: '1rem 2rem',
padding: '1rem 0',
borderBottom: `1px solid ${borders.default}`

},
Expand All @@ -26,11 +26,5 @@ export const styles = createSheet(({ backgrounds, borders, sizes }) => ({
'& > li > span': {
fontWeight: 600
}
},

[`@media (max-width: ${sizes.breakpoint})`]: {
'securityContainer': {
padding: '1rem'
}
}
}))
5 changes: 4 additions & 1 deletion src/components/ServiceContainer/ServiceContainer.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
import React, { PureComponent } from 'react'
import PropTypes from 'prop-types'

import Docs from '../Docs/Docs'
import Method from '../Method/Method'
import { styles } from './ServiceContainer.styles'

@styles
export default class ServiceContainer extends PureComponent {
render () {
const { service, classes, initialSchemaTreeDepth } = this.props
const { title, methods } = service
const { title, docs, methods } = service

return (
<div className={classes.serviceContainer} id={title}>
<h2>{title}</h2>
{docs && <Docs {...docs} />}
{methods.map(
(method) => <Method key={method.link} method={method} initialSchemaTreeDepth={initialSchemaTreeDepth} />
)}
Expand Down
4 changes: 4 additions & 0 deletions src/parser/open-api/schemaParser.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ function getPropertyNode (nodeName, propertyNode, required = false) {
outputNode.defaultValue = propertyNode.default
}

if (propertyNode.externalDocs) {
outputNode.docs = propertyNode.externalDocs
}

if (propertyNode.additionalProperties === false) {
outputNode.additionalProperties = false
}
Expand Down
4 changes: 4 additions & 0 deletions src/parser/open-api/v3/navigationParser.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ export function getServicesMethod ({path, servers, method, request, params, resp
servicesMethod.description = method.description
}

if (method.externalDocs) {
servicesMethod.docs = method.externalDocs
}

if (params) {
servicesMethod.parameters = params
}
Expand Down
Loading