refactor(oas31): concentrate OpenAPI 3.1.0 code to separate plugin (#8475)

Refs #8474
This commit is contained in:
Vladimír Gorej
2023-03-16 12:05:19 +01:00
committed by GitHub
parent ceccb218d3
commit 8b274414ab
35 changed files with 929 additions and 699 deletions

View File

@@ -0,0 +1,45 @@
/**
* @prettier
*/
import React from "react"
import PropTypes from "prop-types"
import { safeBuildUrl } from "core/utils/url"
import { sanitizeUrl } from "core/utils"
class Contact extends React.Component {
static propTypes = {
data: PropTypes.object,
getComponent: PropTypes.func.isRequired,
specSelectors: PropTypes.object.isRequired,
selectedServer: PropTypes.string,
url: PropTypes.string.isRequired,
}
render() {
const { data, getComponent, selectedServer, url: specUrl } = this.props
const name = data.get("name", "the developer")
const url = safeBuildUrl(data.get("url"), specUrl, { selectedServer })
const email = data.get("email")
const Link = getComponent("Link")
return (
<div className="info__contact">
{url && (
<div>
<Link href={sanitizeUrl(url)} target="_blank">
{name} - Website
</Link>
</div>
)}
{email && (
<Link href={sanitizeUrl(`mailto:${email}`)}>
{url ? `Send email to ${name}` : `Contact ${name}`}
</Link>
)}
</div>
)
}
}
export default Contact

View File

@@ -1,102 +1,53 @@
/**
* @prettier
*/
import React from "react"
import PropTypes from "prop-types"
import ImPropTypes from "react-immutable-proptypes"
import { sanitizeUrl } from "core/utils"
import { safeBuildUrl } from "core/utils/url"
export class InfoBasePath extends React.Component {
static propTypes = {
host: PropTypes.string,
basePath: PropTypes.string
basePath: PropTypes.string,
}
render() {
let { host, basePath } = this.props
const { host, basePath } = this.props
return (
<pre className="base-url">
[ Base URL: {host}{basePath} ]
[ Base URL: {host}
{basePath} ]
</pre>
)
}
}
export class Contact extends React.Component {
static propTypes = {
data: PropTypes.object,
getComponent: PropTypes.func.isRequired,
specSelectors: PropTypes.object.isRequired,
selectedServer: PropTypes.string,
url: PropTypes.string.isRequired,
}
render(){
let { data, getComponent, selectedServer, url: specUrl} = this.props
let name = data.get("name") || "the developer"
let url = safeBuildUrl(data.get("url"), specUrl, {selectedServer})
let email = data.get("email")
const Link = getComponent("Link")
return (
<div className="info__contact">
{ url && <div><Link href={ sanitizeUrl(url) } target="_blank">{ name } - Website</Link></div> }
{ email &&
<Link href={sanitizeUrl(`mailto:${email}`)}>
{ url ? `Send email to ${name}` : `Contact ${name}`}
</Link>
}
</div>
)
}
}
export class License extends React.Component {
static propTypes = {
license: PropTypes.object,
getComponent: PropTypes.func.isRequired,
specSelectors: PropTypes.object.isRequired,
selectedServer: PropTypes.string,
url: PropTypes.string.isRequired,
}
render(){
let { license, getComponent, selectedServer, url: specUrl } = this.props
const Link = getComponent("Link")
let name = license.get("name") || "License"
let url = safeBuildUrl(license.get("url"), specUrl, {selectedServer})
return (
<div className="info__license">
{
url ? <Link target="_blank" href={ sanitizeUrl(url) }>{ name }</Link>
: <span>{ name }</span>
}
</div>
)
}
}
export class InfoUrl extends React.PureComponent {
static propTypes = {
url: PropTypes.string.isRequired,
getComponent: PropTypes.func.isRequired
getComponent: PropTypes.func.isRequired,
}
render() {
const { url, getComponent } = this.props
const Link = getComponent("Link")
return <Link target="_blank" href={ sanitizeUrl(url) }><span className="url"> { url }</span></Link>
return (
<Link target="_blank" href={sanitizeUrl(url)}>
<span className="url"> {url}</span>
</Link>
)
}
}
export default class Info extends React.Component {
class Info extends React.Component {
static propTypes = {
title: PropTypes.any,
description: PropTypes.any,
version: PropTypes.any,
info: PropTypes.object,
url: PropTypes.string,
host: PropTypes.string,
@@ -108,16 +59,32 @@ export default class Info extends React.Component {
}
render() {
let { info, url, host, basePath, getComponent, externalDocs, selectedServer, url: specUrl } = this.props
let version = info.get("version")
let description = info.get("description")
let title = info.get("title")
let termsOfServiceUrl = safeBuildUrl(info.get("termsOfService"), specUrl, {selectedServer})
let contact = info.get("contact")
let license = info.get("license")
let rawExternalDocsUrl = externalDocs && externalDocs.get("url")
let externalDocsUrl = safeBuildUrl(rawExternalDocsUrl, specUrl, {selectedServer})
let externalDocsDescription = externalDocs && externalDocs.get("description")
const {
info,
url,
host,
basePath,
getComponent,
externalDocs,
selectedServer,
url: specUrl,
} = this.props
const version = info.get("version")
const description = info.get("description")
const title = info.get("title")
const termsOfServiceUrl = safeBuildUrl(
info.get("termsOfService"),
specUrl,
{ selectedServer }
)
const contactData = info.get("contact")
const licenseData = info.get("license")
const rawExternalDocsUrl = externalDocs && externalDocs.get("url")
const externalDocsUrl = safeBuildUrl(rawExternalDocsUrl, specUrl, {
selectedServer,
})
const externalDocsDescription =
externalDocs && externalDocs.get("description")
const Markdown = getComponent("Markdown", true)
const Link = getComponent("Link")
@@ -125,42 +92,61 @@ export default class Info extends React.Component {
const InfoUrl = getComponent("InfoUrl")
const InfoBasePath = getComponent("InfoBasePath")
const License = getComponent("License")
const Contact = getComponent("Contact")
return (
<div className="info">
<hgroup className="main">
<h2 className="title" >{ title }
{ version && <VersionStamp version={version}></VersionStamp> }
<h2 className="title">
{title}
{version && <VersionStamp version={version}></VersionStamp>}
</h2>
{ host || basePath ? <InfoBasePath host={ host } basePath={ basePath } /> : null }
{ url && <InfoUrl getComponent={getComponent} url={url} /> }
{host || basePath ? (
<InfoBasePath host={host} basePath={basePath} />
) : null}
{url && <InfoUrl getComponent={getComponent} url={url} />}
</hgroup>
<div className="description">
<Markdown source={ description } />
<Markdown source={description} />
</div>
{
termsOfServiceUrl && <div className="info__tos">
<Link target="_blank" href={ sanitizeUrl(termsOfServiceUrl) }>Terms of service</Link>
{termsOfServiceUrl && (
<div className="info__tos">
<Link target="_blank" href={sanitizeUrl(termsOfServiceUrl)}>
Terms of service
</Link>
</div>
}
{contact && contact.size ? <Contact getComponent={getComponent} data={ contact } selectedServer={selectedServer} url={url} /> : null }
{license && license.size ? <License getComponent={getComponent} license={ license } selectedServer={selectedServer} url={url}/> : null }
{ externalDocsUrl ?
<Link className="info__extdocs" target="_blank" href={sanitizeUrl(externalDocsUrl)}>{externalDocsDescription || externalDocsUrl}</Link>
: null }
)}
{contactData?.size > 0 && (
<Contact
getComponent={getComponent}
data={contactData}
selectedServer={selectedServer}
url={url}
/>
)}
{licenseData?.size > 0 && (
<License
getComponent={getComponent}
license={licenseData}
selectedServer={selectedServer}
url={url}
/>
)}
{externalDocsUrl ? (
<Link
className="info__extdocs"
target="_blank"
href={sanitizeUrl(externalDocsUrl)}
>
{externalDocsDescription || externalDocsUrl}
</Link>
) : null}
</div>
)
}
}
Info.propTypes = {
title: PropTypes.any,
description: PropTypes.any,
version: PropTypes.any,
url: PropTypes.string
}
export default Info

View File

@@ -1,37 +1,39 @@
/**
* @prettier
*/
import React from "react"
import PropTypes from "prop-types"
export default class BaseLayout extends React.Component {
static propTypes = {
errSelectors: PropTypes.object.isRequired,
errActions: PropTypes.object.isRequired,
specSelectors: PropTypes.object.isRequired,
oas3Selectors: PropTypes.object.isRequired,
oas3Actions: PropTypes.object.isRequired,
getComponent: PropTypes.func.isRequired
getComponent: PropTypes.func.isRequired,
}
render() {
let {errSelectors, specSelectors, getComponent} = this.props
const { errSelectors, specSelectors, getComponent } = this.props
let SvgAssets = getComponent("SvgAssets")
let InfoContainer = getComponent("InfoContainer", true)
let VersionPragmaFilter = getComponent("VersionPragmaFilter")
let Operations = getComponent("operations", true)
let Models = getComponent("Models", true)
let Webhooks = getComponent("Webhooks", true)
let Row = getComponent("Row")
let Col = getComponent("Col")
let Errors = getComponent("errors", true)
const SvgAssets = getComponent("SvgAssets")
const InfoContainer = getComponent("InfoContainer", true)
const VersionPragmaFilter = getComponent("VersionPragmaFilter")
const Operations = getComponent("operations", true)
const Models = getComponent("Models", true)
const Webhooks = getComponent("Webhooks", true)
const Row = getComponent("Row")
const Col = getComponent("Col")
const Errors = getComponent("errors", true)
const ServersContainer = getComponent("ServersContainer", true)
const SchemesContainer = getComponent("SchemesContainer", true)
const AuthorizeBtnContainer = getComponent("AuthorizeBtnContainer", true)
const FilterContainer = getComponent("FilterContainer", true)
let isSwagger2 = specSelectors.isSwagger2()
let isOAS3 = specSelectors.isOAS3()
const isOpenAPI31 = specSelectors.selectIsOpenAPI31()
const isSwagger2 = specSelectors.isSwagger2()
const isOAS3 = specSelectors.isOAS3()
const isOAS31 = specSelectors.isOAS31()
const isSpecEmpty = !specSelectors.specStr()
@@ -39,44 +41,50 @@ export default class BaseLayout extends React.Component {
let loadingMessage = null
if(loadingStatus === "loading") {
loadingMessage = <div className="info">
<div className="loading-container">
<div className="loading"></div>
if (loadingStatus === "loading") {
loadingMessage = (
<div className="info">
<div className="loading-container">
<div className="loading"></div>
</div>
</div>
</div>
)
}
if(loadingStatus === "failed") {
loadingMessage = <div className="info">
<div className="loading-container">
<h4 className="title">Failed to load API definition.</h4>
<Errors />
if (loadingStatus === "failed") {
loadingMessage = (
<div className="info">
<div className="loading-container">
<h4 className="title">Failed to load API definition.</h4>
<Errors />
</div>
</div>
</div>
)
}
if (loadingStatus === "failedConfig") {
const lastErr = errSelectors.lastError()
const lastErrMsg = lastErr ? lastErr.get("message") : ""
loadingMessage = <div className="info failed-config">
<div className="loading-container">
<h4 className="title">Failed to load remote configuration.</h4>
<p>{lastErrMsg}</p>
loadingMessage = (
<div className="info failed-config">
<div className="loading-container">
<h4 className="title">Failed to load remote configuration.</h4>
<p>{lastErrMsg}</p>
</div>
</div>
</div>
)
}
if(!loadingMessage && isSpecEmpty) {
if (!loadingMessage && isSpecEmpty) {
loadingMessage = <h4>No API definition provided.</h4>
}
if(loadingMessage) {
return <div className="swagger-ui">
<div className="loading-container">
{loadingMessage}
if (loadingMessage) {
return (
<div className="swagger-ui">
<div className="loading-container">{loadingMessage}</div>
</div>
</div>
)
}
const servers = specSelectors.servers()
@@ -87,43 +95,47 @@ export default class BaseLayout extends React.Component {
const hasSecurityDefinitions = !!specSelectors.securityDefinitions()
return (
<div className='swagger-ui'>
<div className="swagger-ui">
<SvgAssets />
<VersionPragmaFilter isSwagger2={isSwagger2} isOAS3={isOAS3} alsoShow={<Errors/>}>
<Errors/>
<VersionPragmaFilter
isSwagger2={isSwagger2}
isOAS3={isOAS3}
alsoShow={<Errors />}
>
<Errors />
<Row className="information-container">
<Col mobile={12}>
<InfoContainer/>
<InfoContainer />
</Col>
</Row>
{hasServers || hasSchemes || hasSecurityDefinitions ? (
<div className="scheme-container">
<Col className="schemes wrapper" mobile={12}>
{hasServers ? (<ServersContainer />) : null}
{hasSchemes ? (<SchemesContainer />) : null}
{hasSecurityDefinitions ? (<AuthorizeBtnContainer />) : null}
{hasServers ? <ServersContainer /> : null}
{hasSchemes ? <SchemesContainer /> : null}
{hasSecurityDefinitions ? <AuthorizeBtnContainer /> : null}
</Col>
</div>
) : null}
<FilterContainer/>
<FilterContainer />
<Row>
<Col mobile={12} desktop={12} >
<Operations/>
<Col mobile={12} desktop={12}>
<Operations />
</Col>
</Row>
{ isOpenAPI31 &&
{isOAS31 && (
<Row className="webhooks-container">
<Col mobile={12} desktop={12} >
<Col mobile={12} desktop={12}>
<Webhooks />
</Col>
</Row>
}
)}
<Row>
<Col mobile={12} desktop={12} >
<Models/>
<Col mobile={12} desktop={12}>
<Models />
</Col>
</Row>
</VersionPragmaFilter>

View File

@@ -0,0 +1,41 @@
/**
* @prettier
*/
import React from "react"
import PropTypes from "prop-types"
import { safeBuildUrl } from "core/utils/url"
import { sanitizeUrl } from "core/utils"
class License extends React.Component {
static propTypes = {
license: PropTypes.object,
getComponent: PropTypes.func.isRequired,
specSelectors: PropTypes.object.isRequired,
selectedServer: PropTypes.string,
url: PropTypes.string.isRequired,
}
render() {
const { license, getComponent, selectedServer, url: specUrl } = this.props
const name = license.get("name", "License")
const url = safeBuildUrl(license.get("url"), specUrl, { selectedServer })
const Link = getComponent("Link")
return (
<div className="info__license">
{url ? (
<div className="info__license__url">
<Link target="_blank" href={sanitizeUrl(url)}>
{name}
</Link>
</div>
) : (
<span>{name}</span>
)}
</div>
)
}
}
export default License