feat: Render external docs links and descriptions (#7559)

Co-authored-by: Tim Lai <timothy.lai@smartbear.com>
This commit is contained in:
Fabian Schneider
2022-08-17 19:42:36 +02:00
committed by GitHub
parent 7dd167b626
commit 6ae2693d47
10 changed files with 443 additions and 14 deletions

View File

@@ -1,6 +1,7 @@
import React, { Component } from "react"
import PropTypes from "prop-types"
import ImPropTypes from "react-immutable-proptypes"
import { sanitizeUrl } from "core/utils"
const propClass = "property"
@@ -25,12 +26,16 @@ export default class ArrayModel extends Component {
let description = schema.get("description")
let items = schema.get("items")
let title = schema.get("title") || displayName || name
let properties = schema.filter( ( v, key) => ["type", "items", "description", "$$ref"].indexOf(key) === -1 )
let properties = schema.filter( ( v, key) => ["type", "items", "description", "$$ref", "externalDocs"].indexOf(key) === -1 )
let externalDocsUrl = schema.getIn(["externalDocs", "url"])
let externalDocsDescription = schema.getIn(["externalDocs", "description"])
const Markdown = getComponent("Markdown", true)
const ModelCollapse = getComponent("ModelCollapse")
const Model = getComponent("Model")
const Property = getComponent("Property")
const Link = getComponent("Link")
const titleEl = title &&
<span className="model-title">
@@ -52,6 +57,11 @@ export default class ArrayModel extends Component {
!description ? (properties.size ? <div className="markdown"></div> : null) :
<Markdown source={ description } />
}
{ externalDocsUrl &&
<div className="external-docs">
<Link target="_blank" href={sanitizeUrl(externalDocsUrl)}>{externalDocsDescription || externalDocsUrl}</Link>
</div>
}
<span>
<Model
{ ...this.props }

View File

@@ -2,6 +2,7 @@ import React, { Component, } from "react"
import PropTypes from "prop-types"
import { List } from "immutable"
import ImPropTypes from "react-immutable-proptypes"
import { sanitizeUrl } from "core/utils"
const braceOpen = "{"
const braceClose = "}"
@@ -44,12 +45,15 @@ export default class ObjectModel extends Component {
let infoProperties = schema
.filter( ( v, key) => ["maxProperties", "minProperties", "nullable", "example"].indexOf(key) !== -1 )
let deprecated = schema.get("deprecated")
let externalDocsUrl = schema.getIn(["externalDocs", "url"])
let externalDocsDescription = schema.getIn(["externalDocs", "description"])
const JumpToPath = getComponent("JumpToPath", true)
const Markdown = getComponent("Markdown", true)
const Model = getComponent("Model")
const ModelCollapse = getComponent("ModelCollapse")
const Property = getComponent("Property")
const Link = getComponent("Link")
const JumpToPathSection = () => {
return <span className="model-jump-to-path"><JumpToPath specPath={specPath} /></span>
@@ -93,6 +97,17 @@ export default class ObjectModel extends Component {
</td>
</tr>
}
{
externalDocsUrl &&
<tr className={"external-docs"}>
<td>
externalDocs:
</td>
<td>
<Link target="_blank" href={sanitizeUrl(externalDocsUrl)}>{externalDocsDescription || externalDocsUrl}</Link>
</td>
</tr>
}
{
!deprecated ? null :
<tr className={"property"}>
@@ -103,7 +118,6 @@ export default class ObjectModel extends Component {
true
</td>
</tr>
}
{
!(properties && properties.size) ? null : properties.entrySeq().filter(

View File

@@ -88,18 +88,14 @@ export default class OperationTag extends React.Component {
</small>
}
{!tagExternalDocsDescription ? null :
{!tagExternalDocsUrl ? null :
<div className="info__externaldocs">
<small>
{tagExternalDocsDescription}
{tagExternalDocsUrl ? ": " : null}
{tagExternalDocsUrl ?
<Link
<Link
href={sanitizeUrl(tagExternalDocsUrl)}
onClick={(e) => e.stopPropagation()}
target="_blank"
>{tagExternalDocsUrl}</Link> : null
}
>{tagExternalDocsDescription || tagExternalDocsUrl}</Link>
</small>
</div>
}

View File

@@ -133,9 +133,11 @@ export default class Operation extends PureComponent {
<div className="opblock-external-docs-wrapper">
<h4 className="opblock-title_normal">Find more details</h4>
<div className="opblock-external-docs">
<span className="opblock-external-docs__description">
<Markdown source={ externalDocs.description } />
</span>
{externalDocs.description &&
<span className="opblock-external-docs__description">
<Markdown source={ externalDocs.description } />
</span>
}
<Link target="_blank" className="opblock-external-docs__link" href={sanitizeUrl(externalDocsUrl)}>{externalDocsUrl}</Link>
</div>
</div> : null

View File

@@ -1,6 +1,6 @@
import React, { Component } from "react"
import PropTypes from "prop-types"
import { getExtensions } from "core/utils"
import { getExtensions, sanitizeUrl } from "core/utils"
const propClass = "property primitive"
@@ -33,12 +33,17 @@ export default class Primitive extends Component {
let description = schema.get("description")
let extensions = getExtensions(schema)
let properties = schema
.filter((_, key) => ["enum", "type", "format", "description", "$$ref"].indexOf(key) === -1)
.filter((_, key) => ["enum", "type", "format", "description", "$$ref", "externalDocs"].indexOf(key) === -1)
.filterNot((_, key) => extensions.has(key))
let externalDocsUrl = schema.getIn(["externalDocs", "url"])
let externalDocsDescription = schema.getIn(["externalDocs", "description"])
const Markdown = getComponent("Markdown", true)
const EnumModel = getComponent("EnumModel")
const Property = getComponent("Property")
const ModelCollapse = getComponent("ModelCollapse")
const Link = getComponent("Link")
const titleEl = title &&
<span className="model-title">
<span className="model-title__text">{title}</span>
@@ -60,6 +65,12 @@ export default class Primitive extends Component {
!description ? null :
<Markdown source={description} />
}
{
externalDocsUrl &&
<div className="external-docs">
<Link target="_blank" href={sanitizeUrl(externalDocsUrl)}>{externalDocsDescription || externalDocsUrl}</Link>
</div>
}
{
xml && xml.size ? (<span><br /><span className={propClass}>xml:</span>
{

View File

@@ -118,6 +118,11 @@
flex: 1;
}
}
.info__externaldocs
{
text-align: right;
}
}
.parameter__type

View File

@@ -108,6 +108,12 @@
color: #6b6b6b;
}
}
.external-docs
{
color: #666;
font-weight: normal;
}
}
table.model
@@ -157,6 +163,19 @@ table.model
vertical-align: top;
}
}
&.external-docs
{
td:first-child
{
font-weight: bold;
}
}
.renderedMarkdown p:first-child
{
margin-top: 0;
}
}
}