feat(swagger-ui-react): rewrite into SSR compatible function component (#9855)
Refs #9243
This commit is contained in:
@@ -1,93 +1,121 @@
|
|||||||
import React from "react"
|
/**
|
||||||
|
* @prettier
|
||||||
|
*/
|
||||||
|
"use client"
|
||||||
|
|
||||||
|
import React, { useEffect, useCallback, useState } from "react"
|
||||||
import PropTypes from "prop-types"
|
import PropTypes from "prop-types"
|
||||||
import SwaggerUIConstructor from "#swagger-ui"
|
import SwaggerUIConstructor from "#swagger-ui"
|
||||||
|
|
||||||
class SwaggerUI extends React.Component {
|
const SwaggerUI = ({
|
||||||
constructor (props) {
|
spec = SwaggerUIConstructor.defaultOptions.spec,
|
||||||
super(props)
|
url = SwaggerUIConstructor.defaultOptions.url,
|
||||||
this.SwaggerUIComponent = null
|
layout = SwaggerUIConstructor.defaultOptions.layout,
|
||||||
this.system = null
|
requestInterceptor = SwaggerUIConstructor.defaultOptions.requestInterceptor,
|
||||||
}
|
responseInterceptor = SwaggerUIConstructor.defaultOptions.responseInterceptor,
|
||||||
|
supportedSubmitMethods = SwaggerUIConstructor.defaultOptions
|
||||||
|
.supportedSubmitMethods,
|
||||||
|
queryConfigEnabled = SwaggerUIConstructor.defaultOptions.queryConfigEnabled,
|
||||||
|
plugins = SwaggerUIConstructor.defaultOptions.plugins,
|
||||||
|
displayOperationId = SwaggerUIConstructor.defaultOptions.displayOperationId,
|
||||||
|
showMutatedRequest = SwaggerUIConstructor.defaultOptions.showMutatedRequest,
|
||||||
|
docExpansion = SwaggerUIConstructor.defaultOptions.docExpansion,
|
||||||
|
defaultModelExpandDepth = SwaggerUIConstructor.defaultOptions
|
||||||
|
.defaultModelExpandDepth,
|
||||||
|
defaultModelsExpandDepth = SwaggerUIConstructor.defaultOptions
|
||||||
|
.defaultModelsExpandDepth,
|
||||||
|
defaultModelRendering = SwaggerUIConstructor.defaultOptions
|
||||||
|
.defaultModelRendering,
|
||||||
|
presets = SwaggerUIConstructor.defaultOptions.presets,
|
||||||
|
deepLinking = SwaggerUIConstructor.defaultOptions.deepLinking,
|
||||||
|
showExtensions = SwaggerUIConstructor.defaultOptions.showExtensions,
|
||||||
|
showCommonExtensions = SwaggerUIConstructor.defaultOptions
|
||||||
|
.showCommonExtensions,
|
||||||
|
filter = SwaggerUIConstructor.defaultOptions.filter,
|
||||||
|
requestSnippetsEnabled = SwaggerUIConstructor.defaultOptions
|
||||||
|
.requestSnippetsEnabled,
|
||||||
|
requestSnippets = SwaggerUIConstructor.defaultOptions.requestSnippets,
|
||||||
|
tryItOutEnabled = SwaggerUIConstructor.defaultOptions.tryItOutEnabled,
|
||||||
|
displayRequestDuration = SwaggerUIConstructor.defaultOptions
|
||||||
|
.displayRequestDuration,
|
||||||
|
withCredentials = SwaggerUIConstructor.defaultOptions.withCredentials,
|
||||||
|
persistAuthorization = SwaggerUIConstructor.defaultOptions
|
||||||
|
.persistAuthorization,
|
||||||
|
oauth2RedirectUrl = SwaggerUIConstructor.defaultOptions.oauth2RedirectUrl,
|
||||||
|
onComplete = null,
|
||||||
|
}) => {
|
||||||
|
const [system, setSystem] = useState(null)
|
||||||
|
const SwaggerUIComponent = system?.getComponent("App", "root")
|
||||||
|
|
||||||
componentDidMount() {
|
const handleComplete = useCallback(() => {
|
||||||
const ui = SwaggerUIConstructor({
|
if (typeof onComplete === "function") {
|
||||||
plugins: this.props.plugins,
|
onComplete()
|
||||||
spec: this.props.spec,
|
}
|
||||||
url: this.props.url,
|
}, [onComplete])
|
||||||
dom_id: null,
|
|
||||||
domNode: null,
|
|
||||||
layout: this.props.layout,
|
|
||||||
defaultModelsExpandDepth: this.props.defaultModelsExpandDepth,
|
|
||||||
defaultModelRendering: this.props.defaultModelRendering,
|
|
||||||
presets: [SwaggerUIConstructor.presets.apis, ...this.props.presets],
|
|
||||||
requestInterceptor: this.props.requestInterceptor,
|
|
||||||
responseInterceptor: this.props.responseInterceptor,
|
|
||||||
onComplete: this.onComplete,
|
|
||||||
docExpansion: this.props.docExpansion,
|
|
||||||
supportedSubmitMethods: this.props.supportedSubmitMethods,
|
|
||||||
queryConfigEnabled: this.props.queryConfigEnabled,
|
|
||||||
defaultModelExpandDepth: this.props.defaultModelExpandDepth,
|
|
||||||
displayOperationId: this.props.displayOperationId,
|
|
||||||
tryItOutEnabled: this.props.tryItOutEnabled,
|
|
||||||
displayRequestDuration: this.props.displayRequestDuration,
|
|
||||||
requestSnippetsEnabled: this.props.requestSnippetsEnabled,
|
|
||||||
requestSnippets: this.props.requestSnippets,
|
|
||||||
showMutatedRequest: this.props.showMutatedRequest,
|
|
||||||
deepLinking: this.props.deepLinking,
|
|
||||||
showExtensions: this.props.showExtensions,
|
|
||||||
showCommonExtensions: this.props.showCommonExtensions,
|
|
||||||
filter: this.props.filter,
|
|
||||||
persistAuthorization: this.props.persistAuthorization,
|
|
||||||
withCredentials: this.props.withCredentials,
|
|
||||||
...(typeof this.props.oauth2RedirectUrl === "string" ? { oauth2RedirectUrl: this.props.oauth2RedirectUrl} : {})
|
|
||||||
})
|
|
||||||
|
|
||||||
this.system = ui
|
useEffect(() => {
|
||||||
this.SwaggerUIComponent = ui.getComponent("App", "root")
|
setSystem(
|
||||||
|
SwaggerUIConstructor({
|
||||||
|
plugins,
|
||||||
|
spec,
|
||||||
|
url,
|
||||||
|
dom_id: null,
|
||||||
|
domNode: null,
|
||||||
|
layout,
|
||||||
|
defaultModelsExpandDepth,
|
||||||
|
defaultModelRendering,
|
||||||
|
presets: [SwaggerUIConstructor.presets.apis, ...presets],
|
||||||
|
requestInterceptor,
|
||||||
|
responseInterceptor,
|
||||||
|
onComplete: handleComplete,
|
||||||
|
docExpansion,
|
||||||
|
supportedSubmitMethods,
|
||||||
|
queryConfigEnabled,
|
||||||
|
defaultModelExpandDepth,
|
||||||
|
displayOperationId,
|
||||||
|
tryItOutEnabled,
|
||||||
|
displayRequestDuration,
|
||||||
|
requestSnippetsEnabled,
|
||||||
|
requestSnippets,
|
||||||
|
showMutatedRequest,
|
||||||
|
deepLinking,
|
||||||
|
showExtensions,
|
||||||
|
showCommonExtensions,
|
||||||
|
filter,
|
||||||
|
persistAuthorization,
|
||||||
|
withCredentials,
|
||||||
|
...(typeof oauth2RedirectUrl === "string"
|
||||||
|
? { oauth2RedirectUrl: oauth2RedirectUrl }
|
||||||
|
: {}),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}, [])
|
||||||
|
|
||||||
this.forceUpdate()
|
useEffect(() => {
|
||||||
}
|
if (system) {
|
||||||
|
const prevStateUrl = system.specSelectors.url()
|
||||||
|
if (url !== prevStateUrl) {
|
||||||
|
system.specActions.updateSpec("")
|
||||||
|
if (url) {
|
||||||
|
system.specActions.updateUrl(url)
|
||||||
|
system.specActions.download(url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
const prevStateSpec = system.specSelectors.specStr()
|
||||||
return this.SwaggerUIComponent ? <this.SwaggerUIComponent /> : null
|
if (spec && spec !== prevStateSpec) {
|
||||||
}
|
const updatedSpec =
|
||||||
|
typeof spec === "object" ? JSON.stringify(spec) : spec
|
||||||
componentDidUpdate(prevProps) {
|
system.specActions.updateSpec(updatedSpec)
|
||||||
const prevStateUrl = this.system.specSelectors.url()
|
|
||||||
if(this.props.url !== prevStateUrl || this.props.url !== prevProps.url) {
|
|
||||||
// flush current content
|
|
||||||
this.system.specActions.updateSpec("")
|
|
||||||
|
|
||||||
if(this.props.url) {
|
|
||||||
// update the internal URL
|
|
||||||
this.system.specActions.updateUrl(this.props.url)
|
|
||||||
// trigger remote definition fetch
|
|
||||||
this.system.specActions.download(this.props.url)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}, [url, spec])
|
||||||
|
|
||||||
const prevStateSpec = this.system.specSelectors.specStr()
|
return SwaggerUIComponent ? <SwaggerUIComponent /> : null
|
||||||
if(this.props.spec && (this.props.spec !== prevStateSpec || this.props.spec !== prevProps.spec)) {
|
|
||||||
if(typeof this.props.spec === "object") {
|
|
||||||
this.system.specActions.updateSpec(JSON.stringify(this.props.spec))
|
|
||||||
} else {
|
|
||||||
this.system.specActions.updateSpec(this.props.spec)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onComplete = () => {
|
|
||||||
if (typeof this.props.onComplete === "function") {
|
|
||||||
return this.props.onComplete(this.system)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SwaggerUI.propTypes = {
|
SwaggerUI.propTypes = {
|
||||||
spec: PropTypes.oneOfType([
|
spec: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
|
||||||
PropTypes.string,
|
|
||||||
PropTypes.object,
|
|
||||||
]),
|
|
||||||
url: PropTypes.string,
|
url: PropTypes.string,
|
||||||
layout: PropTypes.string,
|
layout: PropTypes.string,
|
||||||
requestInterceptor: PropTypes.func,
|
requestInterceptor: PropTypes.func,
|
||||||
@@ -95,7 +123,16 @@ SwaggerUI.propTypes = {
|
|||||||
onComplete: PropTypes.func,
|
onComplete: PropTypes.func,
|
||||||
docExpansion: PropTypes.oneOf(["list", "full", "none"]),
|
docExpansion: PropTypes.oneOf(["list", "full", "none"]),
|
||||||
supportedSubmitMethods: PropTypes.arrayOf(
|
supportedSubmitMethods: PropTypes.arrayOf(
|
||||||
PropTypes.oneOf(["get", "put", "post", "delete", "options", "head", "patch", "trace"])
|
PropTypes.oneOf([
|
||||||
|
"get",
|
||||||
|
"put",
|
||||||
|
"post",
|
||||||
|
"delete",
|
||||||
|
"options",
|
||||||
|
"head",
|
||||||
|
"patch",
|
||||||
|
"trace",
|
||||||
|
])
|
||||||
),
|
),
|
||||||
queryConfigEnabled: PropTypes.bool,
|
queryConfigEnabled: PropTypes.bool,
|
||||||
plugins: PropTypes.oneOfType([
|
plugins: PropTypes.oneOfType([
|
||||||
@@ -112,10 +149,7 @@ SwaggerUI.propTypes = {
|
|||||||
deepLinking: PropTypes.bool,
|
deepLinking: PropTypes.bool,
|
||||||
showExtensions: PropTypes.bool,
|
showExtensions: PropTypes.bool,
|
||||||
showCommonExtensions: PropTypes.bool,
|
showCommonExtensions: PropTypes.bool,
|
||||||
filter: PropTypes.oneOfType([
|
filter: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
|
||||||
PropTypes.string,
|
|
||||||
PropTypes.bool,
|
|
||||||
]),
|
|
||||||
requestSnippetsEnabled: PropTypes.bool,
|
requestSnippetsEnabled: PropTypes.bool,
|
||||||
requestSnippets: PropTypes.object,
|
requestSnippets: PropTypes.object,
|
||||||
tryItOutEnabled: PropTypes.bool,
|
tryItOutEnabled: PropTypes.bool,
|
||||||
@@ -125,37 +159,9 @@ SwaggerUI.propTypes = {
|
|||||||
oauth2RedirectUrl: PropTypes.string,
|
oauth2RedirectUrl: PropTypes.string,
|
||||||
}
|
}
|
||||||
|
|
||||||
SwaggerUI.defaultProps = {
|
|
||||||
spec: SwaggerUIConstructor.defaultOptions.spec,
|
|
||||||
url: SwaggerUIConstructor.defaultOptions.url,
|
|
||||||
layout: SwaggerUIConstructor.defaultOptions.layout,
|
|
||||||
requestInterceptor: SwaggerUIConstructor.defaultOptions.requestInterceptor,
|
|
||||||
responseInterceptor: SwaggerUIConstructor.defaultOptions.responseInterceptor,
|
|
||||||
supportedSubmitMethods: SwaggerUIConstructor.defaultOptions.supportedSubmitMethods,
|
|
||||||
queryConfigEnabled: SwaggerUIConstructor.defaultOptions.queryConfigEnabled,
|
|
||||||
plugins: SwaggerUIConstructor.defaultOptions.plugins,
|
|
||||||
displayOperationId: SwaggerUIConstructor.defaultOptions.displayOperationId,
|
|
||||||
showMutatedRequest: SwaggerUIConstructor.defaultOptions.showMutatedRequest,
|
|
||||||
docExpansion: SwaggerUIConstructor.defaultOptions.docExpansion,
|
|
||||||
defaultModelExpandDepth: SwaggerUIConstructor.defaultOptions.defaultModelExpandDepth,
|
|
||||||
defaultModelsExpandDepth: SwaggerUIConstructor.defaultOptions.defaultModelsExpandDepth,
|
|
||||||
defaultModelRendering: SwaggerUIConstructor.defaultOptions.defaultModelRendering,
|
|
||||||
presets: SwaggerUIConstructor.defaultOptions.presets,
|
|
||||||
deepLinking: SwaggerUIConstructor.defaultOptions.deepLinking,
|
|
||||||
showExtensions: SwaggerUIConstructor.defaultOptions.showExtensions,
|
|
||||||
showCommonExtensions: SwaggerUIConstructor.defaultOptions.showCommonExtensions,
|
|
||||||
filter: SwaggerUIConstructor.defaultOptions.filter,
|
|
||||||
requestSnippetsEnabled: SwaggerUIConstructor.defaultOptions.requestSnippetsEnabled,
|
|
||||||
requestSnippets: SwaggerUIConstructor.defaultOptions.requestSnippets,
|
|
||||||
tryItOutEnabled: SwaggerUIConstructor.defaultOptions.tryItOutEnabled,
|
|
||||||
displayRequestDuration: SwaggerUIConstructor.defaultOptions.displayRequestDuration,
|
|
||||||
withCredentials: SwaggerUIConstructor.defaultOptions.withCredentials,
|
|
||||||
persistAuthorization: SwaggerUIConstructor.defaultOptions.persistAuthorization,
|
|
||||||
oauth2RedirectUrl: undefined,
|
|
||||||
}
|
|
||||||
|
|
||||||
SwaggerUI.System = SwaggerUIConstructor.System
|
SwaggerUI.System = SwaggerUIConstructor.System
|
||||||
SwaggerUI.presets = SwaggerUIConstructor.presets
|
SwaggerUI.presets = SwaggerUIConstructor.presets
|
||||||
SwaggerUI.plugins = SwaggerUIConstructor.plugins
|
SwaggerUI.plugins = SwaggerUIConstructor.plugins
|
||||||
|
SwaggerUI.defaultOptions = SwaggerUIConstructor.defaultOptions
|
||||||
|
|
||||||
export default SwaggerUI
|
export default SwaggerUI
|
||||||
|
|||||||
Reference in New Issue
Block a user